{"version":3,"sources":["ResultLayoutSelector.min__87a2f876e355bf8ecbd9.js","./src/ui/ResultLayoutSelector/ResultLayoutSelector.ts","./src/ui/ResponsiveComponents/ResponsiveResultLayout.ts"],"names":["webpackJsonpCoveo__temporary","196","module","exports","__webpack_require__","__extends","this","extendStatics","Object","setPrototypeOf","__proto__","Array","d","b","p","hasOwnProperty","__","constructor","prototype","create","defineProperty","value","defaultLayout","element","options","bindings","ResultLayoutSelector","ID","preferredLayout","ComponentOptions","initComponentOptions","currentActiveLayouts","bind","onQueryState","MODEL_EVENTS","CHANGE_ONE","QUERY_STATE_ATTRIBUTES","LAYOUT","handleQueryStateChanged","onRootElement","QueryEvents","querySuccess","args","handleQuerySuccess","queryError","handleQueryError","resultLayoutSection","$$","closest","oneRootElement","InitializationEvents","afterComponentsInitialization","populate","afterInitialization","ResponsiveResultLayout","init","root","_this","get","searchInterface","responsiveComponents","isLargeScreenWidth","pick","desktopLayouts","isMediumScreenWidth","tabletLayouts","isSmallScreenWidth","mobileLayouts","enumerable","configurable","changeLayout","layout","performLayoutChange","getCurrentLayout","currentLayout","disableLayouts","layouts","Utils","isNonEmptyArray","each","disableLayout","remainingValidLayouts","difference","keys","isEmpty","logger","error","firstPossibleValidLayout","enableLayout","setLayout","newLayout","contains","enableLayouts","find","restorePreferredLayout","Assert","check","isLayoutDisplayedByButton","getModelValue","setModelValue","lastResults","queryController","getLastResults","usageAnalytics","logCustomEvent","analyticsActionCauseList","resultsLayoutChange","resultsLayoutChangeTo","logSearchEvent","firstQuery","executeQuery","hideButton","allResultLists","resultLists","resultList","showButton","updateSelectorAppearance","getComponents","btn","button","el","addClass","visible","removeClass","results","setAttribute","toString","trigger","ResultListEvents","hasNoResults","length","shouldShowSelector","show","hide","modelLayout","l","undefined","populateArgs","ResultLayoutEvents","populateResultLayout","uniq","map","toLowerCase","validLayouts","addButton","className","caption","append","icon","SVGIcons","icons","SVGDom","addClassToSVGInContainer","prepend","selectAction","AccessibleButton","withElement","withLabel","withSelectAction","withOwner","build","isCurrentLayout","toggleClass","enabled","elem","queryStateModel","QueryStateModel","attributesEnum","val","set","filter","activeLayout","aliases","doExport","exportGlobally","ResultLayout","buildListOption","defaultValue","Component","Initialization","registerAutoCreateComponent","656","657","coveoRoot","responsiveDropdown","SearchInterface","on","handleResizeEvent","component","computeCssClassName","Logger","trace","ResponsiveComponentsManager","register","registerComponent","accept","resultLayout","needSmallMode","enableAndDisableLayouts","needMediumMode","layoutsToDisable","layoutsToEnable","intersection","getResponsiveMode","width","getSmallScreenWidth","getMediumScreenWidth"],"mappings":"AAAAA,8BAA8B,KAExBC,IACA,SAAUC,EAAQC,EAASC,GAEjC,YAEA,IAAIC,GAAaC,MAAQA,KAAKD,WAAc,WACxC,GAAIE,GAAgBC,OAAOC,iBACpBC,uBAA2BC,QAAS,SAAUC,EAAGC,GAAKD,EAAEF,UAAYG,IACvE,SAAUD,EAAGC,GAAK,IAAK,GAAIC,KAAKD,GAAOA,EAAEE,eAAeD,KAAIF,EAAEE,GAAKD,EAAEC,IACzE,OAAO,UAAUF,EAAGC,GAEhB,QAASG,KAAOV,KAAKW,YAAcL,EADnCL,EAAcK,EAAGC,GAEjBD,EAAEM,UAAkB,OAANL,EAAaL,OAAOW,OAAON,IAAMG,EAAGE,UAAYL,EAAEK,UAAW,GAAIF,OAGvFR,QAAOY,eAAejB,EAAS,cAAgBkB,OAAO,ICjBtD,MACA,YACA,QACA,QACA,SACA,QACA,OACA,QACA,QAEA,OACA,OACA,OACA,QACA,QACA,OACA,QACA,OAEA,OACA,OACA,SAGA,OAgBa,GAAAC,cAA6B,MAa1C,mBA4EE,WAAmBC,EAA6BC,EAAgCC,GAAhF,MACE,YAAMF,EAASG,EAAqBC,GAAIF,IAAS,IDxD7C,OCuDa,GAAAF,UAA6B,EAAAC,UA9DxC,EAAAI,gBAA+B,KAgErC,EAAKJ,QAAU,EAAAK,iBAAiBC,qBAAqBP,EAASG,EAAsBF,GAEpF,EAAKO,wBAEL,EAAKC,KAAKC,aAAa,EAAAC,aAAaC,WAAY,EAAAC,uBAAuBC,OAAQ,EAAKC,wBAAwBN,KAAK,IACjH,EAAKA,KAAKO,cAAc,EAAAC,YAAYC,aAAc,SAACC,GAAiC,SAAKC,mBAAmBD,KAC5G,EAAKV,KAAKO,cAAc,EAAAC,YAAYI,WAAY,SAACF,GAA+B,SAAKG,iBAAiBH,KAEtG,EAAKI,oBAAsB,EAAAC,GAAG,EAAKxB,SAASyB,QAAQ,gCAEpD,EAAKhB,KAAKiB,eAAe,EAAAC,qBAAqBC,8BAA+B,WAAM,SAAKC,aACxF,EAAKpB,KAAKiB,eAAe,EAAAC,qBAAqBG,oBAAqB,WAAM,SAAKf,4BAE9E,EAAAgB,uBAAuBC,KAAK,EAAKC,KAAM,MDtE5BC,ECsUf,MA3V0C,QA8FxC,sBAAW,6BDtELC,ICsEN,WACE,MAAIpD,MAAKqD,gBAAgBC,qBAAqBC,qBACrC,EAAAC,KAAKxD,KAAKyB,qBAAsBzB,KAAKkB,QAAQuC,gBAElDzD,KAAKqD,gBAAgBC,qBAAqBI,sBACrC,EAAAF,KAAKxD,KAAKyB,qBAAsBzB,KAAKkB,QAAQyC,eAElD3D,KAAKqD,gBAAgBC,qBAAqBM,qBACrC,EAAAJ,KAAKxD,KAAKyB,qBAAsBzB,KAAKkB,QAAQ2C,eAE/C7D,KAAKyB,sBDpERqC,YAAY,EACZC,cAAc,ICgFb,YAAAC,aAAP,SAAoBC,GAClBjE,KAAKsB,gBAAkB,KACvBtB,KAAKkE,oBAAoBD,IAOpB,YAAAE,iBAAP,WACE,MAAOnE,MAAKoE,eAGP,YAAAC,eAAP,SAAsBC,GAAtB,UACE,IAAI,EAAAC,MAAMC,gBAAgBF,GAAU,CAClC,EAAAG,KAAKH,EAAS,SAAAL,GAAU,SAAKS,cAAcT,IAE3C,IAAIU,GAAwB,EAAAC,WAAW,EAAAC,KAAK7E,KAAKyB,sBAAuB6C,EAGxE,IAFAtE,KAAKsB,gBAAkBtB,KAAKoE,cAEvB,EAAAU,QAAQH,GAGN,CACL3E,KAAK+E,OAAOC,MAAM,8EAClB,IAAIC,GAAwC,EAAAJ,KAAK7E,KAAKyB,sBAAsB,EAC5EzB,MAAKkF,aAAaD,GAClBjF,KAAKmF,UAAUF,OAPoB,CACnC,GAAMG,GAAY,EAAAC,SAASV,EAAuB3E,KAAKoE,eAAiBpE,KAAKoE,cAAgBO,EAAsB,EACnH3E,MAAKkE,oBAAiCkB,MAUrC,YAAAE,cAAP,SAAqBhB,GAArB,UACE,GAAAG,KAAKH,EAAS,SAAAL,GAAU,SAAKiB,aAAajB,KACT,EAAAsB,KAAKjB,EAAS,SAAAL,GAAU,MAAAA,KAAW,EAAK3C,mBAC7CtB,KAAKwF,0BAG3B,YAAAA,uBAAR,WACExF,KAAKkE,oBAAoBlE,KAAKsB,iBAC9BtB,KAAKsB,gBAAkB,MAGjB,YAAA4C,oBAAR,SAA4BD,GAG1B,GAFA,EAAAwB,OAAOC,MAAM1F,KAAK2F,0BAA0B1B,GAAS,mCAEjDA,IAAWjE,KAAKoE,eAA0C,KAAzBpE,KAAK4F,gBAAwB,CAChE5F,KAAK6F,cAAc5B,EACnB,IAAM6B,GAAc9F,KAAK+F,gBAAgBC,gBACzChG,MAAKmF,UAAUlB,EAAQ6B,GACnBA,EACF9F,KAAKiG,eAAeC,eAClB,EAAAC,yBAAyBC,qBAEvBC,sBAAuBpC,GAEzBjE,KAAKiB,UAGPjB,KAAKiG,eAAeK,eAA8C,EAAAH,yBAAyBC,qBACzFC,sBAAuBpC,IAEpBjE,KAAK+F,gBAAgBQ,YACxBvG,KAAK+F,gBAAgBS,kBAMrB,YAAA9B,cAAR,SAAsBT,GAChBjE,KAAK2F,0BAA0B1B,IACjCjE,KAAKyG,WAAWxC,IAIZ,YAAAiB,aAAR,SAAqBjB,GACnB,GAAMyC,GAAiB1G,KAAK2G,WACc,GAAApB,KAAKmB,EAAgB,SAAAE,GAAc,MAAAA,GAAW1F,QAAQ+C,QAAUA,KACjEjE,KAAK2F,0BAA0B1B,KACtEjE,KAAK6G,WAAW5C,GAChBjE,KAAK8G,6BAIT,sBAAY,2BD9EN1D,IC8EN,WACE,MAAOpD,MAAKqD,gBAAgB0D,cAAc,eD5EtCjD,YAAY,EACZC,cAAc,IC8EZ,YAAA0C,WAAR,SAAmBxC,GACjB,GAAIjE,KAAK2F,0BAA0B1B,GAAS,CAC1C,GAAI+C,GAAMhH,KAAKyB,qBAA6BwC,GAAQgD,MACpD,GAAAxE,GAAGuE,EAAIE,IAAIC,SAAS,gBACpBH,EAAII,SAAU,EACdpH,KAAK8G,6BAID,YAAAD,WAAR,SAAmB5C,GACjB,GAAIjE,KAAK2F,0BAA0B1B,GAAS,CAC1C,GAAI+C,GAAMhH,KAAKyB,qBAA6BwC,GAAQgD,MACpD,GAAAxE,GAAGuE,EAAIE,IAAIG,YAAY,gBACvBL,EAAII,SAAU,IAIV,YAAAjC,UAAR,SAAkBlB,EAAqBqD,GACjCrD,IACEjE,KAAKoE,gBACP,EAAA3B,GAAGzC,KAAKyB,qBAAqBzB,KAAKoE,eAAe6C,OAAOC,IAAIG,YAAY,kBACxE,EAAA5E,GAAGzC,KAAKyB,qBAAqBzB,KAAKoE,eAAe6C,OAAOC,IAAIK,aAAa,iBAAgB,GAAMC,aAEjG,EAAA/E,GAAGzC,KAAKyB,qBAAqBwC,GAAQgD,OAAOC,IAAIC,SAAS,kBACzD,EAAA1E,GAAGzC,KAAKyB,qBAAqBwC,GAAQgD,OAAOC,IAAIK,aAAa,iBAAgB,GAAKC,YAClFxH,KAAKoE,cAAgBH,EACrB,EAAAxB,GAAGzC,KAAKiB,SAASwG,QAAQ,EAAAC,iBAAiB1D,cACxCC,OAAQA,EACRqD,QAASA,MAKP,YAAAjF,mBAAR,SAA2BD,GACzBpC,KAAK2H,aAA8C,GAA/BvF,EAAKkF,QAAQA,QAAQM,OACrC5H,KAAK6H,qBACP7H,KAAK8H,OAEL9H,KAAK+H,QAID,YAAA/F,wBAAR,SAAgCI,GAC9B,GAAM4F,GAAchI,KAAK4F,gBACnBR,EAAY,EAAAG,KAAK,EAAAV,KAAK7E,KAAKyB,sBAAuB,SAAAwG,GAAK,MAAAA,KAAMD,QACjDE,KAAd9C,EACFpF,KAAKmF,UAAuBC,GAE5BpF,KAAKmF,UAAuB,EAAAN,KAAK7E,KAAKyB,sBAAsB,KAIxD,YAAAc,iBAAR,SAAyBH,GACvBpC,KAAK2H,cAAe,EACpB3H,KAAK+H,QAGC,YAAAjB,yBAAR,WACM9G,KAAK6H,qBACP7H,KAAK8H,OAEL9H,KAAK+H,QAID,YAAAjF,SAAR,sBACMqF,GAA4C7D,WAChD,GAAA7B,GAAGzC,KAAKkD,MAAMuE,QAAQ,EAAAW,mBAAmBC,qBAAsBF,EAC/D,IAAM7D,GAAU,EAAAgE,KAAKH,EAAa7D,QAAQiE,IAAI,SAAAtE,GAAU,MAAAA,GAAOuE,gBAE/D,GAAA/D,KAAKH,EAAS,SAAAL,GAAU,SAAAwB,OAAOC,MAAM,EAAAL,SAASjE,EAAqBqH,aAAcxE,GAAS,oBACrF,EAAAa,QAAQR,KACX,EAAAG,KAAKH,EAAS,SAAAL,GAAU,SAAKyE,UAAUzE,KAClCjE,KAAK6H,sBACR7H,KAAK+H,SAKH,YAAAW,UAAR,SAAkBzE,GAAlB,WACQ+C,EAAM,EAAAvE,GAAG,QACbkG,UAAW,iCAEPC,EAAU,EAAAnG,GAAG,QAAUkG,UAAW,wCAA0C,EAAAV,EAAEhE,GACpF+C,GAAI6B,OAAOD,EAAQ1B,GAEnB,IAAM4B,GAAO,EAAArG,GAAG,QAAUkG,UAAW,oBAAoB1E,EAAM,gBAAkB,EAAA8E,SAASC,MAAS/E,EAAM,UACzG,GAAAgF,OAAOC,yBAAyBJ,EAAK5B,GAAI,SAASjD,EAAM,QACxD+C,EAAImC,QAAQL,EAAK5B,GAEjB,IAAMkC,GAAe,WAAM,SAAKpF,aAA0BC,KAE1D,GAAI,GAAAoF,kBACDC,YAAYtC,GACZuC,UAAU,EAAAtB,EAAE,mBAAoB,EAAAA,EAAEhE,KAClCuF,iBAAiBJ,GACjBK,UAAUzJ,KAAK0B,MACfgI,OAEH,IAAMC,GAAkB1F,IAAWjE,KAAKoE,aACxC4C,GAAI4C,YAAY,iBAAkBD,GAClC3C,EAAIO,aAAa,eAAgBoC,EAAgBnC,YAEjD,EAAA/E,GAAGzC,KAAKiB,SAAS4H,OAAO7B,EAAIE,IAC5BlH,KAAKyB,qBAAqBwC,IACxBgD,QACEG,SAAS,EACTF,GAAIF,EAAIE,IAEV2C,SAAS,IAIL,YAAA9B,KAAR,WACE,GAAM+B,GAAO9J,KAAKwC,qBAAuBxC,KAAKiB,OAC9C,GAAAwB,GAAGqH,GAAM3C,SAAS,+BAGZ,YAAAW,KAAR,WACE,GAAMgC,GAAO9J,KAAKwC,qBAAuBxC,KAAKiB,OAC9C,GAAAwB,GAAGqH,GAAMzC,YAAY,+BAGf,YAAAzB,cAAR,WACE,MAAO5F,MAAK+J,gBAAgB3G,IAAI,EAAA4G,gBAAgBC,eAAehG,SAGzD,YAAA4B,cAAR,SAAsBqE,GACpBlK,KAAK+J,gBAAgBI,IAAI,EAAAH,gBAAgBC,eAAehG,OAAQiG,IAG1D,YAAArC,mBAAR,WACE,MACE,GAAAhD,KAAK7E,KAAKyB,sBAAsBmG,OAAS,GACzC,EAAAwC,OAAOpK,KAAKyB,qBAAsB,SAAC4I,GAAiC,MAAAA,GAAapD,OAAOG,UAASQ,OAAS,IACzG5H,KAAK2H,cAIF,YAAAhC,0BAAR,SAAkC1B,GAChC,MAAO,GAAAoB,SAAS,EAAAR,KAAK7E,KAAKyB,sBAAuBwC,IAxV5C,EAAA5C,GAAK,uBACL,EAAAiJ,SAAW,gBAEX,EAAAC,SAAW,WAChB,EAAAC,gBACEpJ,qBAAsBA,EACtBqJ,aAAcrJ,KAIJ,EAAAqH,cAA+B,OAAQ,OAAQ,SAatD,EAAAvH,SAcL2C,cAAe,EAAAtC,iBAAiBmJ,iBAA+BC,cAAe,OAAQ,WActFhH,cAAe,EAAApC,iBAAiBmJ,iBAA+BC,cAAe,OAAQ,OAAQ,WAc9FlH,eAAgB,EAAAlC,iBAAiBmJ,iBAA+BC,cAAe,OAAQ,OAAQ,YAyRnG,GA3V0C,EAAAC,UAA7B,GAAAxJ,uBA6Vb,EAAAyJ,eAAeC,4BAA4B1J,ID9BrC2J,IACA,SAAUnL,EAAQC,KAMlBmL,IACA,SAAUpL,EAAQC,EAASC,GAEjC,YAEAI,QAAOY,eAAejB,EAAS,cAAgBkB,OAAO,GEhYtD,YACA,OACA,OACA,OACA,SAEA,QACA,QAGA,aAaE,WAAmBkK,EAAuB5J,EAAYH,EAAsCgK,GAA5F,UAAmB,MAAAD,YAAuB,KAAA5J,KACxCrB,KAAKqD,gBAAmC,EAAAuH,UAAUxH,IAAIpD,KAAKiL,UAAU/D,GAAI,EAAAiE,iBAAiB,GAC1FF,EAAUG,GAAG,iBAAkB,WAC7B,EAAKC,sBAkDX,MA9DgB,GAAApI,KAAd,SAAmBC,EAAmBoI,EAAiCpK,GACrE,IAAK,EAAAuB,GAAGS,GAAMqC,KAAK,IAAI,EAAAqF,UAAUW,oBAAoB,EAAAnK,uBAA0B,CAG7E,WAFa,IAAI,GAAAoK,OAAO,0BACjBC,MAAM,+EAGf,EAAAC,4BAA4BC,SAAS3I,EAAwB,EAAAP,GAAGS,GAAO,EAAA9B,qBAAqBC,GAAIiK,EAAWpK,IAUtG,YAAA0K,kBAAP,SAAyBC,GACvB,MAAIA,aAAkB,GAAAzK,uBACpBpB,KAAK8L,aAAeD,GACb,IAKJ,YAAAR,kBAAP,WACMrL,KAAK+L,gBACP/L,KAAKgM,wBAAuChM,KAAK8L,aAAa5K,QAAQ2C,eAC7D7D,KAAKiM,iBACdjM,KAAKgM,wBAAuChM,KAAK8L,aAAa5K,QAAQyC,eAEtE3D,KAAKgM,wBAAuChM,KAAK8L,aAAa5K,QAAQuC,iBAIlE,YAAAuI,wBAAR,SAAgCvD,GAC9B,GAAMyD,GAAmB,EAAAtH,WAAgB,EAAAxD,qBAAqBqH,aAAcA,GACtE0D,EAAkB,EAAAC,aAAkB,EAAAhL,qBAAqBqH,aAAcA,EAC7EzI,MAAK8L,aAAazH,eAAe6H,GACjClM,KAAK8L,aAAaxG,cAAc6G,IAG1B,YAAAJ,cAAR,WACE,OAAQ/L,KAAKqD,gBAAgBC,qBAAqB+I,qBAChD,IAAK,QACH,OAAO,CACT,KAAK,OACH,MAAOrM,MAAKiL,UAAUqB,SAAWtM,KAAKqD,gBAAgBC,qBAAqBiJ,qBAC7E,SACE,OAAO,IAIL,YAAAN,eAAR,WACE,OAAQjM,KAAKqD,gBAAgBC,qBAAqB+I,qBAChD,IAAK,SACH,OAAO,CACT,KAAK,OACH,MAAOrM,MAAKiL,UAAUqB,SAAWtM,KAAKqD,gBAAgBC,qBAAqBkJ,sBAC7E,SACE,OAAO,IAGf,IAlEa,GAAAxJ","file":"ResultLayoutSelector.min__87a2f876e355bf8ecbd9.js","sourcesContent":["webpackJsonpCoveo__temporary([40],{\n\n/***/ 196:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__webpack_require__(656);\nvar underscore_1 = __webpack_require__(0);\nvar InitializationEvents_1 = __webpack_require__(17);\nvar QueryEvents_1 = __webpack_require__(11);\nvar ResultLayoutEvents_1 = __webpack_require__(129);\nvar ResultListEvents_1 = __webpack_require__(29);\nvar Assert_1 = __webpack_require__(5);\nvar Model_1 = __webpack_require__(18);\nvar QueryStateModel_1 = __webpack_require__(13);\nvar GlobalExports_1 = __webpack_require__(3);\nvar Strings_1 = __webpack_require__(6);\nvar Dom_1 = __webpack_require__(1);\nvar SVGDom_1 = __webpack_require__(15);\nvar SVGIcons_1 = __webpack_require__(12);\nvar Utils_1 = __webpack_require__(4);\nvar AnalyticsActionListMeta_1 = __webpack_require__(10);\nvar Component_1 = __webpack_require__(7);\nvar ComponentOptions_1 = __webpack_require__(8);\nvar Initialization_1 = __webpack_require__(2);\nvar ResponsiveResultLayout_1 = __webpack_require__(657);\nvar AccessibleButton_1 = __webpack_require__(16);\nexports.defaultLayout = 'list';\n/**\n * The ResultLayoutSelector component allows the end user to switch between multiple {@link ResultList} components that have\n * different {@link ResultList.options.layout} values.\n *\n * This component automatically populates itself with buttons to switch between the ResultList components that have a\n * valid layout value (see the {@link ValidLayout} type).\n *\n * See also the [Result Layouts](https://docs.coveo.com/en/360/) documentation.\n *\n * @availablesince [February 2018 Release (v2.3826.10)](https://docs.coveo.com/en/410/#february-2018-release-v2382610)\n */\nvar ResultLayoutSelector = /** @class */ (function (_super) {\n __extends(ResultLayoutSelector, _super);\n /**\n * Creates a new ResultLayoutSelector component.\n * @param element The HTMLElement on which to instantiate the component.\n * @param options The options for the ResultLayout component.\n * @param bindings The bindings that the component requires to function normally. If not set, these will be\n * automatically resolved (with a slower execution time).\n */\n function ResultLayoutSelector(element, options, bindings) {\n var _this = _super.call(this, element, ResultLayoutSelector.ID, bindings) || this;\n _this.element = element;\n _this.options = options;\n _this.preferredLayout = null;\n _this.options = ComponentOptions_1.ComponentOptions.initComponentOptions(element, ResultLayoutSelector, options);\n _this.currentActiveLayouts = {};\n _this.bind.onQueryState(Model_1.MODEL_EVENTS.CHANGE_ONE, QueryStateModel_1.QUERY_STATE_ATTRIBUTES.LAYOUT, _this.handleQueryStateChanged.bind(_this));\n _this.bind.onRootElement(QueryEvents_1.QueryEvents.querySuccess, function (args) { return _this.handleQuerySuccess(args); });\n _this.bind.onRootElement(QueryEvents_1.QueryEvents.queryError, function (args) { return _this.handleQueryError(args); });\n _this.resultLayoutSection = Dom_1.$$(_this.element).closest('.coveo-result-layout-section');\n _this.bind.oneRootElement(InitializationEvents_1.InitializationEvents.afterComponentsInitialization, function () { return _this.populate(); });\n _this.bind.oneRootElement(InitializationEvents_1.InitializationEvents.afterInitialization, function () { return _this.handleQueryStateChanged(); });\n ResponsiveResultLayout_1.ResponsiveResultLayout.init(_this.root, _this, {});\n return _this;\n }\n Object.defineProperty(ResultLayoutSelector.prototype, \"activeLayouts\", {\n get: function () {\n if (this.searchInterface.responsiveComponents.isLargeScreenWidth()) {\n return underscore_1.pick(this.currentActiveLayouts, this.options.desktopLayouts);\n }\n if (this.searchInterface.responsiveComponents.isMediumScreenWidth()) {\n return underscore_1.pick(this.currentActiveLayouts, this.options.tabletLayouts);\n }\n if (this.searchInterface.responsiveComponents.isSmallScreenWidth()) {\n return underscore_1.pick(this.currentActiveLayouts, this.options.mobileLayouts);\n }\n return this.currentActiveLayouts;\n },\n enumerable: true,\n configurable: true\n });\n /**\n * Changes the current layout.\n *\n * Also logs a `resultLayoutChange` event in the usage analytics with the new layout as metadeta.\n *\n * Triggers a new query.\n *\n * @param layout The new layout. The page must contain a valid {@link ResultList} component with a matching\n * {@link ResultList.options.layout} value for this method to work.\n */\n ResultLayoutSelector.prototype.changeLayout = function (layout) {\n this.preferredLayout = null;\n this.performLayoutChange(layout);\n };\n /**\n * Gets the current layout (`list`, `card` or `table`).\n * @returns {string} The current current layout.\n */\n ResultLayoutSelector.prototype.getCurrentLayout = function () {\n return this.currentLayout;\n };\n ResultLayoutSelector.prototype.disableLayouts = function (layouts) {\n var _this = this;\n if (Utils_1.Utils.isNonEmptyArray(layouts)) {\n underscore_1.each(layouts, function (layout) { return _this.disableLayout(layout); });\n var remainingValidLayouts = underscore_1.difference(underscore_1.keys(this.currentActiveLayouts), layouts);\n this.preferredLayout = this.currentLayout;\n if (!underscore_1.isEmpty(remainingValidLayouts)) {\n var newLayout = underscore_1.contains(remainingValidLayouts, this.currentLayout) ? this.currentLayout : remainingValidLayouts[0];\n this.performLayoutChange(newLayout);\n }\n else {\n this.logger.error('Cannot disable the last valid layout ... Re-enabling the first one possible');\n var firstPossibleValidLayout = underscore_1.keys(this.currentActiveLayouts)[0];\n this.enableLayout(firstPossibleValidLayout);\n this.setLayout(firstPossibleValidLayout);\n }\n }\n };\n ResultLayoutSelector.prototype.enableLayouts = function (layouts) {\n var _this = this;\n underscore_1.each(layouts, function (layout) { return _this.enableLayout(layout); });\n var preferredLayoutAvailable = underscore_1.find(layouts, function (layout) { return layout === _this.preferredLayout; });\n preferredLayoutAvailable && this.restorePreferredLayout();\n };\n ResultLayoutSelector.prototype.restorePreferredLayout = function () {\n this.performLayoutChange(this.preferredLayout);\n this.preferredLayout = null;\n };\n ResultLayoutSelector.prototype.performLayoutChange = function (layout) {\n Assert_1.Assert.check(this.isLayoutDisplayedByButton(layout), 'Layout not available or invalid');\n if (layout !== this.currentLayout || this.getModelValue() === '') {\n this.setModelValue(layout);\n var lastResults = this.queryController.getLastResults();\n this.setLayout(layout, lastResults);\n if (lastResults) {\n this.usageAnalytics.logCustomEvent(AnalyticsActionListMeta_1.analyticsActionCauseList.resultsLayoutChange, {\n resultsLayoutChangeTo: layout\n }, this.element);\n }\n else {\n this.usageAnalytics.logSearchEvent(AnalyticsActionListMeta_1.analyticsActionCauseList.resultsLayoutChange, {\n resultsLayoutChangeTo: layout\n });\n if (!this.queryController.firstQuery) {\n this.queryController.executeQuery();\n }\n }\n }\n };\n ResultLayoutSelector.prototype.disableLayout = function (layout) {\n if (this.isLayoutDisplayedByButton(layout)) {\n this.hideButton(layout);\n }\n };\n ResultLayoutSelector.prototype.enableLayout = function (layout) {\n var allResultLists = this.resultLists;\n var atLeastOneResultListCanShowLayout = underscore_1.find(allResultLists, function (resultList) { return resultList.options.layout == layout; });\n if (atLeastOneResultListCanShowLayout && this.isLayoutDisplayedByButton(layout)) {\n this.showButton(layout);\n this.updateSelectorAppearance();\n }\n };\n Object.defineProperty(ResultLayoutSelector.prototype, \"resultLists\", {\n get: function () {\n return this.searchInterface.getComponents('ResultList');\n },\n enumerable: true,\n configurable: true\n });\n ResultLayoutSelector.prototype.hideButton = function (layout) {\n if (this.isLayoutDisplayedByButton(layout)) {\n var btn = this.currentActiveLayouts[layout].button;\n Dom_1.$$(btn.el).addClass('coveo-hidden');\n btn.visible = false;\n this.updateSelectorAppearance();\n }\n };\n ResultLayoutSelector.prototype.showButton = function (layout) {\n if (this.isLayoutDisplayedByButton(layout)) {\n var btn = this.currentActiveLayouts[layout].button;\n Dom_1.$$(btn.el).removeClass('coveo-hidden');\n btn.visible = true;\n }\n };\n ResultLayoutSelector.prototype.setLayout = function (layout, results) {\n if (layout) {\n if (this.currentLayout) {\n Dom_1.$$(this.currentActiveLayouts[this.currentLayout].button.el).removeClass('coveo-selected');\n Dom_1.$$(this.currentActiveLayouts[this.currentLayout].button.el).setAttribute('aria-pressed', false.toString());\n }\n Dom_1.$$(this.currentActiveLayouts[layout].button.el).addClass('coveo-selected');\n Dom_1.$$(this.currentActiveLayouts[layout].button.el).setAttribute('aria-pressed', true.toString());\n this.currentLayout = layout;\n Dom_1.$$(this.element).trigger(ResultListEvents_1.ResultListEvents.changeLayout, {\n layout: layout,\n results: results\n });\n }\n };\n ResultLayoutSelector.prototype.handleQuerySuccess = function (args) {\n this.hasNoResults = args.results.results.length == 0;\n if (this.shouldShowSelector()) {\n this.show();\n }\n else {\n this.hide();\n }\n };\n ResultLayoutSelector.prototype.handleQueryStateChanged = function (args) {\n var modelLayout = this.getModelValue();\n var newLayout = underscore_1.find(underscore_1.keys(this.currentActiveLayouts), function (l) { return l === modelLayout; });\n if (newLayout !== undefined) {\n this.setLayout(newLayout);\n }\n else {\n this.setLayout(underscore_1.keys(this.currentActiveLayouts)[0]);\n }\n };\n ResultLayoutSelector.prototype.handleQueryError = function (args) {\n this.hasNoResults = true;\n this.hide();\n };\n ResultLayoutSelector.prototype.updateSelectorAppearance = function () {\n if (this.shouldShowSelector()) {\n this.show();\n }\n else {\n this.hide();\n }\n };\n ResultLayoutSelector.prototype.populate = function () {\n var _this = this;\n var populateArgs = { layouts: [] };\n Dom_1.$$(this.root).trigger(ResultLayoutEvents_1.ResultLayoutEvents.populateResultLayout, populateArgs);\n var layouts = underscore_1.uniq(populateArgs.layouts.map(function (layout) { return layout.toLowerCase(); }));\n underscore_1.each(layouts, function (layout) { return Assert_1.Assert.check(underscore_1.contains(ResultLayoutSelector.validLayouts, layout), 'Invalid layout'); });\n if (!underscore_1.isEmpty(layouts)) {\n underscore_1.each(layouts, function (layout) { return _this.addButton(layout); });\n if (!this.shouldShowSelector()) {\n this.hide();\n }\n }\n };\n ResultLayoutSelector.prototype.addButton = function (layout) {\n var _this = this;\n var btn = Dom_1.$$('span', {\n className: 'coveo-result-layout-selector'\n });\n var caption = Dom_1.$$('span', { className: 'coveo-result-layout-selector-caption' }, Strings_1.l(layout));\n btn.append(caption.el);\n var icon = Dom_1.$$('span', { className: \"coveo-icon coveo-\" + layout + \"-layout-icon\" }, SVGIcons_1.SVGIcons.icons[layout + \"Layout\"]);\n SVGDom_1.SVGDom.addClassToSVGInContainer(icon.el, \"coveo-\" + layout + \"-svg\");\n btn.prepend(icon.el);\n var selectAction = function () { return _this.changeLayout(layout); };\n new AccessibleButton_1.AccessibleButton()\n .withElement(btn)\n .withLabel(Strings_1.l('DisplayResultsAs', Strings_1.l(layout)))\n .withSelectAction(selectAction)\n .withOwner(this.bind)\n .build();\n var isCurrentLayout = layout === this.currentLayout;\n btn.toggleClass('coveo-selected', isCurrentLayout);\n btn.setAttribute('aria-pressed', isCurrentLayout.toString());\n Dom_1.$$(this.element).append(btn.el);\n this.currentActiveLayouts[layout] = {\n button: {\n visible: true,\n el: btn.el\n },\n enabled: true\n };\n };\n ResultLayoutSelector.prototype.hide = function () {\n var elem = this.resultLayoutSection || this.element;\n Dom_1.$$(elem).addClass('coveo-result-layout-hidden');\n };\n ResultLayoutSelector.prototype.show = function () {\n var elem = this.resultLayoutSection || this.element;\n Dom_1.$$(elem).removeClass('coveo-result-layout-hidden');\n };\n ResultLayoutSelector.prototype.getModelValue = function () {\n return this.queryStateModel.get(QueryStateModel_1.QueryStateModel.attributesEnum.layout);\n };\n ResultLayoutSelector.prototype.setModelValue = function (val) {\n this.queryStateModel.set(QueryStateModel_1.QueryStateModel.attributesEnum.layout, val);\n };\n ResultLayoutSelector.prototype.shouldShowSelector = function () {\n return (underscore_1.keys(this.currentActiveLayouts).length > 1 &&\n underscore_1.filter(this.currentActiveLayouts, function (activeLayout) { return activeLayout.button.visible; }).length > 1 &&\n !this.hasNoResults);\n };\n ResultLayoutSelector.prototype.isLayoutDisplayedByButton = function (layout) {\n return underscore_1.contains(underscore_1.keys(this.currentActiveLayouts), layout);\n };\n ResultLayoutSelector.ID = 'ResultLayoutSelector';\n ResultLayoutSelector.aliases = ['ResultLayout'];\n ResultLayoutSelector.doExport = function () {\n GlobalExports_1.exportGlobally({\n ResultLayoutSelector: ResultLayoutSelector,\n ResultLayout: ResultLayoutSelector\n });\n };\n ResultLayoutSelector.validLayouts = ['list', 'card', 'table'];\n /**\n * The component options\n * @componentOptions\n */\n ResultLayoutSelector.options = {\n /**\n * Specifies the layouts that should be available when the search page is displayed in mobile mode.\n *\n * By default, the mobile mode breakpoint is at 480 px screen width.\n *\n * To change this default value, use the [responsiveSmallBreakpoint]{@link SearchInterface.options.responsiveSmallBreakpoint} option.\n *\n * When the breakpoint is reached, layouts that are not specified becomes inactive and the linked result list will be disabled.\n *\n * The possible values for layouts are `list`, `card`, `table`.\n *\n * The default value is `card`, `table`.\n */\n mobileLayouts: ComponentOptions_1.ComponentOptions.buildListOption({ defaultValue: ['card', 'table'] }),\n /**\n * Specifies the layouts that should be available when the search page is displayed in tablet mode.\n *\n * By default, the tablet mode breakpoint is at 800 px screen width.\n *\n * To change this default value, use the [responsiveMediumBreakpoint]{@link SearchInterface.options.responsiveMediumBreakpoint} option.\n *\n * When the breakpoint is reached, layouts that are not specified becomes inactive and the linked result list will be disabled.\n *\n * The possible values for layouts are `list`, `card`, `table`.\n *\n * The default value is `list`, `card`, `table`.\n */\n tabletLayouts: ComponentOptions_1.ComponentOptions.buildListOption({ defaultValue: ['list', 'card', 'table'] }),\n /**\n * Specifies the layouts that should be available when the search page is displayed in desktop mode.\n *\n * By default, the desktop mode breakpoint is any screen size over 800 px.\n *\n * To change this default value, use the [responsiveMediumBreakpoint]{@link SearchInterface.options.responsiveMediumBreakpoint} option.\n *\n * When the breakpoint is reached, layouts that are not specified becomes inactive and the linked result list will be disabled.\n *\n * The possible values for layouts are `list`, `card`, `table`.\n *\n * The default value is `list`, `card`, `table`.\n */\n desktopLayouts: ComponentOptions_1.ComponentOptions.buildListOption({ defaultValue: ['list', 'card', 'table'] })\n };\n return ResultLayoutSelector;\n}(Component_1.Component));\nexports.ResultLayoutSelector = ResultLayoutSelector;\nInitialization_1.Initialization.registerAutoCreateComponent(ResultLayoutSelector);\n\n\n/***/ }),\n\n/***/ 656:\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n\n/***/ 657:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar underscore_1 = __webpack_require__(0);\nvar Logger_1 = __webpack_require__(9);\nvar Dom_1 = __webpack_require__(1);\nvar Component_1 = __webpack_require__(7);\nvar ResultLayoutSelector_1 = __webpack_require__(196);\nvar SearchInterface_1 = __webpack_require__(19);\nvar ResponsiveComponentsManager_1 = __webpack_require__(60);\nvar ResponsiveResultLayout = /** @class */ (function () {\n function ResponsiveResultLayout(coveoRoot, ID, options, responsiveDropdown) {\n var _this = this;\n this.coveoRoot = coveoRoot;\n this.ID = ID;\n this.searchInterface = Component_1.Component.get(this.coveoRoot.el, SearchInterface_1.SearchInterface, false);\n coveoRoot.on('state:change:t', function () {\n _this.handleResizeEvent();\n });\n }\n ResponsiveResultLayout.init = function (root, component, options) {\n if (!Dom_1.$$(root).find(\".\" + Component_1.Component.computeCssClassName(ResultLayoutSelector_1.ResultLayoutSelector))) {\n var logger = new Logger_1.Logger('ResponsiveResultLayout');\n logger.trace('No ResultLayout component found : Cannot instantiate ResponsiveResultLayout');\n return;\n }\n ResponsiveComponentsManager_1.ResponsiveComponentsManager.register(ResponsiveResultLayout, Dom_1.$$(root), ResultLayoutSelector_1.ResultLayoutSelector.ID, component, options);\n };\n ResponsiveResultLayout.prototype.registerComponent = function (accept) {\n if (accept instanceof ResultLayoutSelector_1.ResultLayoutSelector) {\n this.resultLayout = accept;\n return true;\n }\n return false;\n };\n ResponsiveResultLayout.prototype.handleResizeEvent = function () {\n if (this.needSmallMode()) {\n this.enableAndDisableLayouts(this.resultLayout.options.mobileLayouts);\n }\n else if (this.needMediumMode()) {\n this.enableAndDisableLayouts(this.resultLayout.options.tabletLayouts);\n }\n else {\n this.enableAndDisableLayouts(this.resultLayout.options.desktopLayouts);\n }\n };\n ResponsiveResultLayout.prototype.enableAndDisableLayouts = function (validLayouts) {\n var layoutsToDisable = underscore_1.difference(ResultLayoutSelector_1.ResultLayoutSelector.validLayouts, validLayouts);\n var layoutsToEnable = underscore_1.intersection(ResultLayoutSelector_1.ResultLayoutSelector.validLayouts, validLayouts);\n this.resultLayout.disableLayouts(layoutsToDisable);\n this.resultLayout.enableLayouts(layoutsToEnable);\n };\n ResponsiveResultLayout.prototype.needSmallMode = function () {\n switch (this.searchInterface.responsiveComponents.getResponsiveMode()) {\n case 'small':\n return true;\n case 'auto':\n return this.coveoRoot.width() <= this.searchInterface.responsiveComponents.getSmallScreenWidth();\n default:\n return false;\n }\n };\n ResponsiveResultLayout.prototype.needMediumMode = function () {\n switch (this.searchInterface.responsiveComponents.getResponsiveMode()) {\n case 'medium':\n return true;\n case 'auto':\n return this.coveoRoot.width() <= this.searchInterface.responsiveComponents.getMediumScreenWidth();\n default:\n return false;\n }\n };\n return ResponsiveResultLayout;\n}());\nexports.ResponsiveResultLayout = ResponsiveResultLayout;\n\n\n/***/ })\n\n});\n\n\n// WEBPACK FOOTER //\n// ResultLayoutSelector.min__87a2f876e355bf8ecbd9.js","import 'styling/_ResultLayoutSelector';\nimport { contains, difference, each, filter, find, isEmpty, keys, uniq, pick } from 'underscore';\nimport { InitializationEvents } from '../../events/InitializationEvents';\nimport { IQueryErrorEventArgs, IQuerySuccessEventArgs, QueryEvents } from '../../events/QueryEvents';\nimport { IResultLayoutPopulateArgs, ResultLayoutEvents } from '../../events/ResultLayoutEvents';\nimport { IChangeLayoutEventArgs, ResultListEvents } from '../../events/ResultListEvents';\nimport { Assert } from '../../misc/Assert';\nimport { IAttributesChangedEventArg, MODEL_EVENTS } from '../../models/Model';\nimport { QueryStateModel, QUERY_STATE_ATTRIBUTES } from '../../models/QueryStateModel';\nimport { IQueryResults } from '../../rest/QueryResults';\nimport { exportGlobally } from '../../GlobalExports';\nimport { l } from '../../strings/Strings';\nimport { $$ } from '../../utils/Dom';\nimport { SVGDom } from '../../utils/SVGDom';\nimport { SVGIcons } from '../../utils/SVGIcons';\nimport { Utils } from '../../utils/Utils';\nimport { analyticsActionCauseList, IAnalyticsResultsLayoutChange } from '../Analytics/AnalyticsActionListMeta';\nimport { Component } from '../Base/Component';\nimport { IComponentBindings } from '../Base/ComponentBindings';\nimport { ComponentOptions } from '../Base/ComponentOptions';\nimport { Initialization } from '../Base/Initialization';\nimport { ResponsiveResultLayout } from '../ResponsiveComponents/ResponsiveResultLayout';\nimport { ValidLayout } from './ValidLayout';\nimport ResultListModule = require('../ResultList/ResultList');\nimport { AccessibleButton } from '../../utils/AccessibleButton';\n\nexport interface IActiveLayouts {\n button: {\n el: HTMLElement;\n visible: boolean;\n };\n enabled: boolean;\n}\n\nexport interface IResultLayoutOptions {\n mobileLayouts: string[];\n tabletLayouts: string[];\n desktopLayouts: string[];\n}\n\nexport const defaultLayout: ValidLayout = 'list';\n\n/**\n * The ResultLayoutSelector component allows the end user to switch between multiple {@link ResultList} components that have\n * different {@link ResultList.options.layout} values.\n *\n * This component automatically populates itself with buttons to switch between the ResultList components that have a\n * valid layout value (see the {@link ValidLayout} type).\n *\n * See also the [Result Layouts](https://docs.coveo.com/en/360/) documentation.\n *\n * @availablesince [February 2018 Release (v2.3826.10)](https://docs.coveo.com/en/410/#february-2018-release-v2382610)\n */\nexport class ResultLayoutSelector extends Component {\n static ID = 'ResultLayoutSelector';\n static aliases = ['ResultLayout'];\n\n static doExport = () => {\n exportGlobally({\n ResultLayoutSelector: ResultLayoutSelector,\n ResultLayout: ResultLayoutSelector\n });\n };\n\n public static validLayouts: ValidLayout[] = ['list', 'card', 'table'];\n\n public currentLayout: ValidLayout;\n private preferredLayout: ValidLayout = null;\n private currentActiveLayouts: { [key: string]: IActiveLayouts };\n\n private resultLayoutSection: HTMLElement;\n private hasNoResults: boolean;\n\n /**\n * The component options\n * @componentOptions\n */\n static options: IResultLayoutOptions = {\n /**\n * Specifies the layouts that should be available when the search page is displayed in mobile mode.\n *\n * By default, the mobile mode breakpoint is at 480 px screen width.\n *\n * To change this default value, use the [responsiveSmallBreakpoint]{@link SearchInterface.options.responsiveSmallBreakpoint} option.\n *\n * When the breakpoint is reached, layouts that are not specified becomes inactive and the linked result list will be disabled.\n *\n * The possible values for layouts are `list`, `card`, `table`.\n *\n * The default value is `card`, `table`.\n */\n mobileLayouts: ComponentOptions.buildListOption({ defaultValue: ['card', 'table'] }),\n /**\n * Specifies the layouts that should be available when the search page is displayed in tablet mode.\n *\n * By default, the tablet mode breakpoint is at 800 px screen width.\n *\n * To change this default value, use the [responsiveMediumBreakpoint]{@link SearchInterface.options.responsiveMediumBreakpoint} option.\n *\n * When the breakpoint is reached, layouts that are not specified becomes inactive and the linked result list will be disabled.\n *\n * The possible values for layouts are `list`, `card`, `table`.\n *\n * The default value is `list`, `card`, `table`.\n */\n tabletLayouts: ComponentOptions.buildListOption({ defaultValue: ['list', 'card', 'table'] }),\n /**\n * Specifies the layouts that should be available when the search page is displayed in desktop mode.\n *\n * By default, the desktop mode breakpoint is any screen size over 800 px.\n *\n * To change this default value, use the [responsiveMediumBreakpoint]{@link SearchInterface.options.responsiveMediumBreakpoint} option.\n *\n * When the breakpoint is reached, layouts that are not specified becomes inactive and the linked result list will be disabled.\n *\n * The possible values for layouts are `list`, `card`, `table`.\n *\n * The default value is `list`, `card`, `table`.\n */\n desktopLayouts: ComponentOptions.buildListOption({ defaultValue: ['list', 'card', 'table'] })\n };\n\n /**\n * Creates a new ResultLayoutSelector component.\n * @param element The HTMLElement on which to instantiate the component.\n * @param options The options for the ResultLayout component.\n * @param bindings The bindings that the component requires to function normally. If not set, these will be\n * automatically resolved (with a slower execution time).\n */\n constructor(public element: HTMLElement, public options?: IResultLayoutOptions, bindings?: IComponentBindings) {\n super(element, ResultLayoutSelector.ID, bindings);\n this.options = ComponentOptions.initComponentOptions(element, ResultLayoutSelector, options);\n\n this.currentActiveLayouts = {};\n\n this.bind.onQueryState(MODEL_EVENTS.CHANGE_ONE, QUERY_STATE_ATTRIBUTES.LAYOUT, this.handleQueryStateChanged.bind(this));\n this.bind.onRootElement(QueryEvents.querySuccess, (args: IQuerySuccessEventArgs) => this.handleQuerySuccess(args));\n this.bind.onRootElement(QueryEvents.queryError, (args: IQueryErrorEventArgs) => this.handleQueryError(args));\n\n this.resultLayoutSection = $$(this.element).closest('.coveo-result-layout-section');\n\n this.bind.oneRootElement(InitializationEvents.afterComponentsInitialization, () => this.populate());\n this.bind.oneRootElement(InitializationEvents.afterInitialization, () => this.handleQueryStateChanged());\n\n ResponsiveResultLayout.init(this.root, this, {});\n }\n\n public get activeLayouts(): { [key: string]: IActiveLayouts } {\n if (this.searchInterface.responsiveComponents.isLargeScreenWidth()) {\n return pick(this.currentActiveLayouts, this.options.desktopLayouts);\n }\n if (this.searchInterface.responsiveComponents.isMediumScreenWidth()) {\n return pick(this.currentActiveLayouts, this.options.tabletLayouts);\n }\n if (this.searchInterface.responsiveComponents.isSmallScreenWidth()) {\n return pick(this.currentActiveLayouts, this.options.mobileLayouts);\n }\n return this.currentActiveLayouts;\n }\n\n /**\n * Changes the current layout.\n *\n * Also logs a `resultLayoutChange` event in the usage analytics with the new layout as metadeta.\n *\n * Triggers a new query.\n *\n * @param layout The new layout. The page must contain a valid {@link ResultList} component with a matching\n * {@link ResultList.options.layout} value for this method to work.\n */\n public changeLayout(layout: ValidLayout) {\n this.preferredLayout = null;\n this.performLayoutChange(layout);\n }\n\n /**\n * Gets the current layout (`list`, `card` or `table`).\n * @returns {string} The current current layout.\n */\n public getCurrentLayout() {\n return this.currentLayout;\n }\n\n public disableLayouts(layouts: ValidLayout[]) {\n if (Utils.isNonEmptyArray(layouts)) {\n each(layouts, layout => this.disableLayout(layout));\n\n let remainingValidLayouts = difference(keys(this.currentActiveLayouts), layouts);\n this.preferredLayout = this.currentLayout;\n\n if (!isEmpty(remainingValidLayouts)) {\n const newLayout = contains(remainingValidLayouts, this.currentLayout) ? this.currentLayout : remainingValidLayouts[0];\n this.performLayoutChange(newLayout);\n } else {\n this.logger.error('Cannot disable the last valid layout ... Re-enabling the first one possible');\n let firstPossibleValidLayout = keys(this.currentActiveLayouts)[0];\n this.enableLayout(firstPossibleValidLayout);\n this.setLayout(firstPossibleValidLayout);\n }\n }\n }\n\n public enableLayouts(layouts: ValidLayout[]) {\n each(layouts, layout => this.enableLayout(layout));\n const preferredLayoutAvailable = find(layouts, layout => layout === this.preferredLayout);\n preferredLayoutAvailable && this.restorePreferredLayout();\n }\n\n private restorePreferredLayout() {\n this.performLayoutChange(this.preferredLayout);\n this.preferredLayout = null;\n }\n\n private performLayoutChange(layout: ValidLayout) {\n Assert.check(this.isLayoutDisplayedByButton(layout), 'Layout not available or invalid');\n\n if (layout !== this.currentLayout || this.getModelValue() === '') {\n this.setModelValue(layout);\n const lastResults = this.queryController.getLastResults();\n this.setLayout(layout, lastResults);\n if (lastResults) {\n this.usageAnalytics.logCustomEvent(\n analyticsActionCauseList.resultsLayoutChange,\n {\n resultsLayoutChangeTo: layout\n },\n this.element\n );\n } else {\n this.usageAnalytics.logSearchEvent(analyticsActionCauseList.resultsLayoutChange, {\n resultsLayoutChangeTo: layout\n });\n if (!this.queryController.firstQuery) {\n this.queryController.executeQuery();\n }\n }\n }\n }\n\n private disableLayout(layout: ValidLayout) {\n if (this.isLayoutDisplayedByButton(layout)) {\n this.hideButton(layout);\n }\n }\n\n private enableLayout(layout: ValidLayout) {\n const allResultLists = this.resultLists;\n const atLeastOneResultListCanShowLayout = find(allResultLists, resultList => resultList.options.layout == layout);\n if (atLeastOneResultListCanShowLayout && this.isLayoutDisplayedByButton(layout)) {\n this.showButton(layout);\n this.updateSelectorAppearance();\n }\n }\n\n private get resultLists(): ResultListModule.ResultList[] {\n return this.searchInterface.getComponents('ResultList');\n }\n\n private hideButton(layout: ValidLayout) {\n if (this.isLayoutDisplayedByButton(layout)) {\n let btn = this.currentActiveLayouts[layout].button;\n $$(btn.el).addClass('coveo-hidden');\n btn.visible = false;\n this.updateSelectorAppearance();\n }\n }\n\n private showButton(layout: ValidLayout) {\n if (this.isLayoutDisplayedByButton(layout)) {\n let btn = this.currentActiveLayouts[layout].button;\n $$(btn.el).removeClass('coveo-hidden');\n btn.visible = true;\n }\n }\n\n private setLayout(layout: ValidLayout, results?: IQueryResults) {\n if (layout) {\n if (this.currentLayout) {\n $$(this.currentActiveLayouts[this.currentLayout].button.el).removeClass('coveo-selected');\n $$(this.currentActiveLayouts[this.currentLayout].button.el).setAttribute('aria-pressed', false.toString());\n }\n $$(this.currentActiveLayouts[layout].button.el).addClass('coveo-selected');\n $$(this.currentActiveLayouts[layout].button.el).setAttribute('aria-pressed', true.toString());\n this.currentLayout = layout;\n $$(this.element).trigger(ResultListEvents.changeLayout, {\n layout: layout,\n results: results\n });\n }\n }\n\n private handleQuerySuccess(args: IQuerySuccessEventArgs) {\n this.hasNoResults = args.results.results.length == 0;\n if (this.shouldShowSelector()) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n private handleQueryStateChanged(args?: IAttributesChangedEventArg) {\n const modelLayout = this.getModelValue();\n const newLayout = find(keys(this.currentActiveLayouts), l => l === modelLayout);\n if (newLayout !== undefined) {\n this.setLayout(newLayout);\n } else {\n this.setLayout(keys(this.currentActiveLayouts)[0]);\n }\n }\n\n private handleQueryError(args: IQueryErrorEventArgs) {\n this.hasNoResults = true;\n this.hide();\n }\n\n private updateSelectorAppearance() {\n if (this.shouldShowSelector()) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n private populate() {\n let populateArgs: IResultLayoutPopulateArgs = { layouts: [] };\n $$(this.root).trigger(ResultLayoutEvents.populateResultLayout, populateArgs);\n const layouts = uniq(populateArgs.layouts.map(layout => layout.toLowerCase()));\n\n each(layouts, layout => Assert.check(contains(ResultLayoutSelector.validLayouts, layout), 'Invalid layout'));\n if (!isEmpty(layouts)) {\n each(layouts, layout => this.addButton(layout));\n if (!this.shouldShowSelector()) {\n this.hide();\n }\n }\n }\n\n private addButton(layout: string) {\n const btn = $$('span', {\n className: 'coveo-result-layout-selector'\n });\n const caption = $$('span', { className: 'coveo-result-layout-selector-caption' }, l(layout));\n btn.append(caption.el);\n\n const icon = $$('span', { className: `coveo-icon coveo-${layout}-layout-icon` }, SVGIcons.icons[`${layout}Layout`]);\n SVGDom.addClassToSVGInContainer(icon.el, `coveo-${layout}-svg`);\n btn.prepend(icon.el);\n\n const selectAction = () => this.changeLayout(layout);\n\n new AccessibleButton()\n .withElement(btn)\n .withLabel(l('DisplayResultsAs', l(layout)))\n .withSelectAction(selectAction)\n .withOwner(this.bind)\n .build();\n\n const isCurrentLayout = layout === this.currentLayout;\n btn.toggleClass('coveo-selected', isCurrentLayout);\n btn.setAttribute('aria-pressed', isCurrentLayout.toString());\n\n $$(this.element).append(btn.el);\n this.currentActiveLayouts[layout] = {\n button: {\n visible: true,\n el: btn.el\n },\n enabled: true\n };\n }\n\n private hide() {\n const elem = this.resultLayoutSection || this.element;\n $$(elem).addClass('coveo-result-layout-hidden');\n }\n\n private show() {\n const elem = this.resultLayoutSection || this.element;\n $$(elem).removeClass('coveo-result-layout-hidden');\n }\n\n private getModelValue(): string {\n return this.queryStateModel.get(QueryStateModel.attributesEnum.layout);\n }\n\n private setModelValue(val: string) {\n this.queryStateModel.set(QueryStateModel.attributesEnum.layout, val);\n }\n\n private shouldShowSelector() {\n return (\n keys(this.currentActiveLayouts).length > 1 &&\n filter(this.currentActiveLayouts, (activeLayout: IActiveLayouts) => activeLayout.button.visible).length > 1 &&\n !this.hasNoResults\n );\n }\n\n private isLayoutDisplayedByButton(layout: ValidLayout) {\n return contains(keys(this.currentActiveLayouts), layout);\n }\n}\n\nInitialization.registerAutoCreateComponent(ResultLayoutSelector);\n\n\n\n// WEBPACK FOOTER //\n// ./src/ui/ResultLayoutSelector/ResultLayoutSelector.ts","import { difference, intersection } from 'underscore';\nimport { Logger } from '../../misc/Logger';\nimport { $$, Dom } from '../../utils/Dom';\nimport { Component } from '../Base/Component';\nimport { ResultLayoutSelector } from '../ResultLayoutSelector/ResultLayoutSelector';\nimport { ValidLayout } from '../ResultLayoutSelector/ValidLayout';\nimport { SearchInterface } from '../SearchInterface/SearchInterface';\nimport { IResponsiveComponent, IResponsiveComponentOptions, ResponsiveComponentsManager } from './ResponsiveComponentsManager';\nimport { ResponsiveDropdown } from './ResponsiveDropdown/ResponsiveDropdown';\n\nexport class ResponsiveResultLayout implements IResponsiveComponent {\n private searchInterface: SearchInterface;\n private resultLayout: ResultLayoutSelector;\n\n public static init(root: HTMLElement, component: ResultLayoutSelector, options: IResponsiveComponentOptions) {\n if (!$$(root).find(`.${Component.computeCssClassName(ResultLayoutSelector)}`)) {\n let logger = new Logger('ResponsiveResultLayout');\n logger.trace('No ResultLayout component found : Cannot instantiate ResponsiveResultLayout');\n return;\n }\n ResponsiveComponentsManager.register(ResponsiveResultLayout, $$(root), ResultLayoutSelector.ID, component, options);\n }\n\n constructor(public coveoRoot: Dom, public ID: string, options: IResponsiveComponentOptions, responsiveDropdown?: ResponsiveDropdown) {\n this.searchInterface = Component.get(this.coveoRoot.el, SearchInterface, false);\n coveoRoot.on('state:change:t', () => {\n this.handleResizeEvent();\n });\n }\n\n public registerComponent(accept: Component) {\n if (accept instanceof ResultLayoutSelector) {\n this.resultLayout = accept;\n return true;\n }\n return false;\n }\n\n public handleResizeEvent() {\n if (this.needSmallMode()) {\n this.enableAndDisableLayouts(this.resultLayout.options.mobileLayouts);\n } else if (this.needMediumMode()) {\n this.enableAndDisableLayouts(this.resultLayout.options.tabletLayouts);\n } else {\n this.enableAndDisableLayouts(this.resultLayout.options.desktopLayouts);\n }\n }\n\n private enableAndDisableLayouts(validLayouts: ValidLayout[]) {\n const layoutsToDisable = difference(ResultLayoutSelector.validLayouts, validLayouts);\n const layoutsToEnable = intersection(ResultLayoutSelector.validLayouts, validLayouts);\n this.resultLayout.disableLayouts(layoutsToDisable);\n this.resultLayout.enableLayouts(layoutsToEnable);\n }\n\n private needSmallMode(): boolean {\n switch (this.searchInterface.responsiveComponents.getResponsiveMode()) {\n case 'small':\n return true;\n case 'auto':\n return this.coveoRoot.width() <= this.searchInterface.responsiveComponents.getSmallScreenWidth();\n default:\n return false;\n }\n }\n\n private needMediumMode(): boolean {\n switch (this.searchInterface.responsiveComponents.getResponsiveMode()) {\n case 'medium':\n return true;\n case 'auto':\n return this.coveoRoot.width() <= this.searchInterface.responsiveComponents.getMediumScreenWidth();\n default:\n return false;\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/ui/ResponsiveComponents/ResponsiveResultLayout.ts"],"sourceRoot":""}