UNPKG

isomorphic-search

Version:
253 lines (222 loc) 7.55 kB
(function (global, factory) { if (typeof define === "function" && define.amd) { define(['exports'], factory); } else if (typeof exports !== "undefined") { factory(exports); } else { var mod = { exports: {} }; factory(mod.exports); global.abstraction = mod.exports; } })(this, function (exports) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); /** * Search module's abstraction */ var identifier = 'id'; var label = 'name'; var abstraction = { // Set the identifying property among the objects in the list. identifier: identifier, // Set the labeling property among the objects in the list. label: label, // The notification system used when set-up fails. See control.set method. notify: console ? console.log : function (error) { return error; }, // Set default parent selector. parent: 'header', // Empowers searching by representing the current search criteria. searchBy: false, // Threshold for error when matching search to potential results. threshold: 0.2, // Search parameters. keys: [{ name: identifier, weight: 0.3 }, { name: label, weight: 0.7 }], // Represents icon classes. icon: { search: 'fa-search', cancel: 'fa-close' }, // Options passed to the search engine. set options(options) { var existing = Object.create(this._options || null); delete this._options; this._options = Object.assign(existing, options); }, get options() { return this._options = Object.assign({ keys: this.keys, threshold: this.threshold }, this._options); }, // Classes and other identifiers to be attached to elements. set attr(attr) { var existing = Object.create(this._attr || null); delete this._attr; this._attr = Object.assign(existing, attr); }, get attr() { // @TODO Abstract. var defaults = { body: 'body', container: 'search', parent: this.parent, input: 'search-field', hidden: 'invisible', instructions: 'instructions', menu: 'search-menu', noResults: 'no-results', result: 'result', results: 'search-results', resultsList: 'search-results-list', searchFieldContainer: 'search-field-container', searchContainer: 'search-container', submit: 'search-submit', title: 'search-title' }; return this._attr = Object.assign(defaults, this._attr || null); }, // Elements set el(element) { var existing = Object.create(this._el || null); delete this._el; this._el = Object.assign(existing, element); }, get el() { var existing = this._el, elements = this.attr, _el = {}; Object.keys(elements).forEach(function (el) { if (el === 'parent' || el === 'body') { _el[el] = elements[el]; } else { _el[el] = '.' + elements[el]; } }); return this._el = _el; }, // DOM Nodes set $el(element) { var existing = Object.create(this._$el || null); delete this._$el; this._$el = Object.assign(existing, element); }, get $el() { var existing = this._$el, el = this.el, _$el = {}; Object.keys(el).forEach(function (element) { var isWrapper = ['body', 'container', 'parent'].indexOf(element) !== -1; if (!isWrapper) { _$el[element] = $(el.container).find(el[element]); } else { _$el[element] = $(el[element]); } }); return this._$el = _$el; }, validate: function validate(data) { if (!data) { return this.messages.unavailable; } if (!data.length) { return this.messages.empty; } return true; }, // Errors messages: { empty: { message: 'The search list is empty.', name: 'empty', type: 'warn' }, engine: { message: 'The search feature requires an engine.', name: 'engine', type: 'warn' }, noResults: { message: 'Your search returned no results.', name: 'no results', type: 'info' }, unavailable: { message: 'The search list is unavailable.', name: 'unavailable', type: 'warn' } }, // Metadata event default method. metadataCallback: function metadataCallback(event, search) { return { event: event, search: search }; }, // Elements' metadata set metadata(metadata) { var existing = Object.create(this._metadata || null); delete this._metadata; this._metadata = Object.assign(existing, metadata); }, get metadata() { var defaults = { input: { placeholder: 'Search', cancel: this.metadataCallback, change: this.metadataCallback, focus: this.metadataCallback }, results: { instructions: 'Choose from the list.' } }; return this._metadata = Object.assign(defaults, this._metadata || null); }, // Templates. template: { error: function error(_ref) { var attr = _ref.attr; return '<div class="' + attr.noResults + '">\n We found no results matching your search.\n </div>'; }, form: function form(_ref2) { var icon = _ref2.icon, attr = _ref2.attr, placeholder = _ref2.metadata.input.placeholder; return '<div class="' + attr.container + '">\n <div class="' + attr.searchFieldContainer + '">\n <input class="' + attr.input + '" placeholder="' + placeholder + '" type="text" />\n <div class="' + attr.menu + '">\n <i class="' + attr.submit + ' fa ' + icon.search + '"></i>\n </div>\n </div>\n </div>'; }, header: function header(title) { return '<h1>' + title + '</h1>'; }, // @TODO Compute `id` & `name` from `this.label` & `this.identifier`. list: function list(_ref3, _ref4) { var id = _ref3.id, name = _ref3.name; var attr = _ref4.attr; return '<li class="' + attr.result + '" data-id="' + id + '" data-name="' + name + '">\n ' + name + '\n </li>'; }, noResults: function noResults(_ref5) { var attr = _ref5.attr, messages = _ref5.messages; return '<div class="' + attr.noResults + '">' + messages.noResults.message + '</div>'; }, result: function result(_ref6) { var attr = _ref6.attr; return '<div class="' + attr.hidden + ' ' + attr.searchResults + '"></div>'; }, results: function results(_ref7) { var attr = _ref7.attr, metadata = _ref7.metadata; var _metadata$results = metadata.results, className = _metadata$results.className, instructions = _metadata$results.instructions, title = _metadata$results.title; return '<div class="' + attr.results + ' ' + attr.hidden + '">\n ' + (title ? '<div class="' + attr.title + '">' + title + '</div>' : '') + '\n ' + (instructions ? '<div class="' + attr.instructions + '">' + instructions + '</div>' : '') + '\n <ul class="' + className + ' ' + attr.resultsList + '"></ul>\n </div>'; } } }; exports.default = abstraction; });