@lrnwebcomponents/simple-search
Advanced tools
Comparing version 0.0.35 to 0.0.36
@@ -1,95 +0,115 @@ | ||
import { html, Polymer } from "@polymer/polymer/polymer-legacy.js"; | ||
import { dom } from "@polymer/polymer/lib/legacy/polymer.dom.js"; | ||
var $_documentContainer = document.createElement("div"); | ||
$_documentContainer.setAttribute("style", "display: none;"); | ||
/** | ||
* Copyright 2018 The Pennsylvania State University | ||
* @license Apache-2.0, see License.md for full text. | ||
*/ | ||
import { html, PolymerElement } from "@polymer/polymer/polymer-element.js"; | ||
$_documentContainer.innerHTML = `<dom-module id="simple-search-content"> | ||
<template> | ||
<style> | ||
:host #content { | ||
@apply --simple-search-content; | ||
} | ||
:host #content[match-number]{ | ||
color: var(--simple-search-match-text-color, #000); | ||
background-color: var(--simple-search-match-bg-color, #f0f0f0); | ||
border: 1px solid; | ||
border-color: var(--simple-search-match-border-color, #ddd); | ||
padding: 0.16px 4px; | ||
border-radius: 0.16px; | ||
font-weight: bold; | ||
@apply --simple-search-match; | ||
} | ||
</style> | ||
<span id="content"> | ||
<template is="dom-repeat" items="[[_searchedContent]]"> | ||
<span match-number\$="[[item.matchNumber]]" tabindex\$="[[_getTabIndex(item.matchNumber)]]">[[item.text]]</span> | ||
</template> | ||
</span> | ||
</template> | ||
</dom-module>`; | ||
document.head.appendChild($_documentContainer); | ||
export { SimpleSearchContent }; | ||
/** | ||
`simple-search-content` | ||
An inline element that can be searched with the seimple-search element | ||
* `simple-search-content` | ||
* `Content that can be searched with simple-search` | ||
* | ||
* | ||
* @microcopy - the mental model for this element | ||
* | ||
* ```<simple-search-content | ||
* content="[[content]]" // inline content to be searched | ||
* </simple-search-content>``` | ||
* | ||
* CSS Variables for matched content: | ||
* ```color: var(--simple-search-match-text-color, #000); | ||
* background-color: var(--simple-search-match-background-color, #f0f0f0); | ||
* border-color: var(--simple-search-match-border-color, #ddd); | ||
* @apply --simple-search-match;``` | ||
* | ||
* @polymer | ||
* @customElement | ||
* @demo demo/index.html | ||
*/ | ||
class SimpleSearchContent extends PolymerElement { | ||
static get is() { | ||
return "simple-search-content"; | ||
} | ||
@demo demo/index.html | ||
static get properties() { | ||
return { | ||
/** | ||
* Original content. For example: "The quick brown fox jumps over the lazy dog." | ||
*/ | ||
content: { | ||
type: String, | ||
value: null | ||
} | ||
}; | ||
} | ||
@microcopy - the mental model for this element | ||
<simple-search-content | ||
content="[[content]]" // inline content to be searched | ||
</simple-search-content> | ||
// render function | ||
static get template() { | ||
return html` | ||
<style> | ||
:host #content { | ||
@apply --simple-search-content; | ||
} | ||
:host #content[match-number] { | ||
color: var(--simple-search-match-text-color, #000); | ||
background-color: var(--simple-search-match-bg-color, #f0f0f0); | ||
border: 1px solid; | ||
border-color: var(--simple-search-match-border-color, #ddd); | ||
padding: 0.16px 4px; | ||
border-radius: 0.16px; | ||
font-weight: bold; | ||
@apply --simple-search-match; | ||
} | ||
</style> | ||
<span id="content"> | ||
<template is="dom-repeat" items="[[_searchedContent]]"> | ||
<span | ||
match-number\$="[[item.matchNumber]]" | ||
tabindex\$="[[_getTabIndex(item.matchNumber)]]" | ||
>[[item.text]]</span | ||
> | ||
</template> | ||
</span> | ||
`; | ||
} | ||
CSS Variables for matched content: | ||
color: var(--simple-search-match-text-color, #000); | ||
background-color: var(--simple-search-match-background-color, #f0f0f0); | ||
border-color: var(--simple-search-match-border-color, #ddd); | ||
@apply --simple-search-match; | ||
*/ | ||
Polymer({ | ||
is: "simple-search-content", | ||
properties: { | ||
/** | ||
* Original content. For example: "The quick brown fox jumps over the lazy dog." | ||
*/ | ||
content: { | ||
type: String, | ||
value: null | ||
} | ||
}, | ||
/** | ||
* associates simple-search-content with a simple-search | ||
* | ||
* @param {object} the simple-search element | ||
*/ | ||
enableSearch: function(searchObject) { | ||
enableSearch(searchObject) { | ||
let root = this, | ||
content = [{ matched: false, text: root.content }]; | ||
if (content[0].text === null) content[0].text = dom(root).innerHTML; | ||
if (content[0].text === null) content[0].text = root.innerHTML; | ||
// set rendered content to default unsearched content | ||
root.setContent(content); | ||
this.setContent(content); | ||
// listen for changes to search | ||
searchObject.addEventListener("search", function() { | ||
searchObject.addEventListener("simple-search", function() { | ||
// set rendered content to default unsearched content to clear old results | ||
root.setContent(content); | ||
this.setContent(content); | ||
// set rendered content to default search results | ||
root.setContent(searchObject.findMatches(content)); | ||
this.setContent(searchObject.findMatches(content)); | ||
}); | ||
// listen for navigation through results | ||
searchObject.addEventListener("goto-result", function(e) { | ||
root.focus(e.detail); | ||
searchObject.addEventListener("goto-result", e => { | ||
this.focus(e.detail); | ||
}); | ||
}, | ||
} | ||
/** | ||
* sets array of content to be rendered | ||
* | ||
* @param {array} an array of searchable content | ||
*/ | ||
setContent: function(newContent) { | ||
setContent(newContent) { | ||
this._searchedContent = newContent; | ||
}, | ||
} | ||
/** | ||
* sets focus on a matched result based on match number | ||
* | ||
* @param {number} the number of a search result | ||
*/ | ||
focus: function(matchNumber) { | ||
focus(matchNumber) { | ||
let result = this.$.content.querySelector( | ||
@@ -99,9 +119,12 @@ '[match-number="' + matchNumber + '"]' | ||
if (result !== undefined && result !== null) result.focus(); | ||
}, | ||
} | ||
/** | ||
* gets tab index based on whether item is a match that can be focused on | ||
* | ||
* @param {number} the number of a search result | ||
*/ | ||
_getTabIndex: function(matchNumber) { | ||
_getTabIndex(matchNumber) { | ||
return matchNumber !== undefined && matchNumber !== null ? "1" : ""; | ||
} | ||
}); | ||
} | ||
customElements.define(SimpleSearchContent.is, SimpleSearchContent); |
@@ -14,3 +14,3 @@ { | ||
}, | ||
"version": "0.0.35", | ||
"version": "0.0.36", | ||
"description": "Automated conversion of simple-search", | ||
@@ -29,3 +29,3 @@ "repository": { | ||
"build": "../../node_modules/.bin/gulp && ../../node_modules/.bin/rollup -c && ../../node_modules/.bin/prettier --ignore-path ../../.prettierignore --write '**/*.{js,json}'", | ||
"dev": "open ./src && concurrently --kill-others 'yarn run watch' 'yarn run serve'", | ||
"dev": "concurrently --kill-others \"yarn run watch\" \"yarn run serve\"", | ||
"watch": "../../node_modules/.bin/gulp dev", | ||
@@ -46,3 +46,3 @@ "serve": "polymer serve --npm --module-resolution=node --open", | ||
"devDependencies": { | ||
"@lrnwebcomponents/deduping-fix": "^0.0.35", | ||
"@lrnwebcomponents/deduping-fix": "^0.0.36", | ||
"@polymer/iron-component-page": "github:PolymerElements/iron-component-page", | ||
@@ -67,3 +67,3 @@ "@polymer/iron-demo-helpers": "3.0.2", | ||
], | ||
"gitHead": "71dcc2b61045070a009e654226e6c0892f11a854" | ||
"gitHead": "3bf677e6744e92117f1958f79ee85cc7d9f89452" | ||
} |
@@ -1,1 +0,1 @@ | ||
define(["./node_modules/@polymer/polymer/polymer-legacy.js","./node_modules/@polymer/iron-icons/iron-icons.js","./node_modules/@polymer/paper-input/paper-input.js","./node_modules/@polymer/paper-tooltip/paper-tooltip.js","./lib/simple-search-content.js"],function(_polymerLegacy,_ironIcons,_paperInput,_paperTooltip,_simpleSearchContent){"use strict";function _templateObject_dd16da20f1e411e8a99f5dc819e27ed9(){var data=babelHelpers.taggedTemplateLiteral(["\n <custom-style>\n <style is=\"custom-style\">\n :host {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n width: 100%;\n }\n :host #input {\n flex-grow: 2;\n margin-right: 4px;\n --paper-input-container-input-color: var(--simple-search-input-text-color, #000);\n --paper-input-container-focus-color: var(--simple-search-input-line-color, #000);\n --paper-input-container-color: var(--simple-search-input-placeholder-color, #222);\n color: var(--simple-search-input-placeholder-color, #222);\n @apply --simple-search-container;\n }\n :host #xofy {\n margin: 8px;\n }\n :host button {\n margin: 8px 0 8px;\n color: var(--simple-search-button-color, #111);\n background-color: var(--simple-search-button-bg-color, #eee);\n border-color: var(--simple-search-button-border-color, #ccc);\n @apply --simple-search-button;\n }\n :host button:not([disabled]):focus,\n :host button:not([disabled]):hover {\n cursor: pointer;\n color: var(--simple-search-button-hover-color, #000);\n background-color: var(--simple-search-button-hover-bg-color, #fff);\n border-color: var(--simple-search-button-hover-border-color, #ddd);\n @apply --simple-search-button-hover;\n }\n :host button[disabled] {\n cursor: not-allowed;\n color: var(--simple-search-button-disabled-color, #999);\n background-color: var(--simple-search-button-disabled-bg-color, #eee);\n border-color: var(--simple-search-button-disabled-border-color, #ccc);\n @apply --simple-search-button-disabled;\n }\n :host button:not([controls]) {\n display: none;\n }\n :host [shrink-hide] {\n display: none;\n }\n </style>\n </custom-style>\n <paper-input id=\"input\" always-float-label$=\"[[alwaysFloatLabel]]\" label=\"[[searchInputLabel]]\" no-label-float$=\"[[noLabelFloat]]\">\n <iron-icon icon=\"[[searchInputIcon]]\" slot=\"prefix\"></iron-icon>\n </paper-input>\n <div id=\"xofy\" shrink-hide$=\"[[noSearch]]\"></div>\n <div shrink-hide$=\"[[noResults]]\">\n <button id=\"prev\" aria-label=\"[[prevButtonLabel]]\" aria-role=\"button\" controls$=\"[[controls]]\" disabled$=\"[[prevButtonDisabled]]\" tabindex=\"0\">\n <iron-icon icon=\"[[prevButtonIcon]]\"></iron-icon>\n </button>\n <paper-tooltip for=\"prev\">[[prevButtonLabel]]</paper-tooltip>\n <button id=\"next\" aria-label=\"[[nextButtonLabel]]\" aria-role=\"button\" controls$=\"[[controls]]\" disabled$=\"[[nextButtonDisabled]]\" tabindex=\"0\">\n <iron-icon icon$=\"[[nextButtonIcon]]\"></iron-icon>\n </button>\n <paper-tooltip for=\"next\">[[nextButtonLabel]]</paper-tooltip>\n </div>\n"],["\n <custom-style>\n <style is=\"custom-style\">\n :host {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n width: 100%;\n }\n :host #input {\n flex-grow: 2;\n margin-right: 4px;\n --paper-input-container-input-color: var(--simple-search-input-text-color, #000);\n --paper-input-container-focus-color: var(--simple-search-input-line-color, #000);\n --paper-input-container-color: var(--simple-search-input-placeholder-color, #222);\n color: var(--simple-search-input-placeholder-color, #222);\n @apply --simple-search-container;\n }\n :host #xofy {\n margin: 8px;\n }\n :host button {\n margin: 8px 0 8px;\n color: var(--simple-search-button-color, #111);\n background-color: var(--simple-search-button-bg-color, #eee);\n border-color: var(--simple-search-button-border-color, #ccc);\n @apply --simple-search-button;\n }\n :host button:not([disabled]):focus,\n :host button:not([disabled]):hover {\n cursor: pointer;\n color: var(--simple-search-button-hover-color, #000);\n background-color: var(--simple-search-button-hover-bg-color, #fff);\n border-color: var(--simple-search-button-hover-border-color, #ddd);\n @apply --simple-search-button-hover;\n }\n :host button[disabled] {\n cursor: not-allowed;\n color: var(--simple-search-button-disabled-color, #999);\n background-color: var(--simple-search-button-disabled-bg-color, #eee);\n border-color: var(--simple-search-button-disabled-border-color, #ccc);\n @apply --simple-search-button-disabled;\n }\n :host button:not([controls]) {\n display: none;\n }\n :host [shrink-hide] {\n display: none;\n }\n </style>\n </custom-style>\n <paper-input id=\"input\" always-float-label\\$=\"[[alwaysFloatLabel]]\" label=\"[[searchInputLabel]]\" no-label-float\\$=\"[[noLabelFloat]]\">\n <iron-icon icon=\"[[searchInputIcon]]\" slot=\"prefix\"></iron-icon>\n </paper-input>\n <div id=\"xofy\" shrink-hide\\$=\"[[noSearch]]\"></div>\n <div shrink-hide\\$=\"[[noResults]]\">\n <button id=\"prev\" aria-label=\"[[prevButtonLabel]]\" aria-role=\"button\" controls\\$=\"[[controls]]\" disabled\\$=\"[[prevButtonDisabled]]\" tabindex=\"0\">\n <iron-icon icon=\"[[prevButtonIcon]]\"></iron-icon>\n </button>\n <paper-tooltip for=\"prev\">[[prevButtonLabel]]</paper-tooltip>\n <button id=\"next\" aria-label=\"[[nextButtonLabel]]\" aria-role=\"button\" controls\\$=\"[[controls]]\" disabled\\$=\"[[nextButtonDisabled]]\" tabindex=\"0\">\n <iron-icon icon\\$=\"[[nextButtonIcon]]\"></iron-icon>\n </button>\n <paper-tooltip for=\"next\">[[nextButtonLabel]]</paper-tooltip>\n </div>\n"]);_templateObject_dd16da20f1e411e8a99f5dc819e27ed9=function _templateObject_dd16da20f1e411e8a99f5dc819e27ed9(){return data};return data}(0,_polymerLegacy.Polymer)({_template:(0,_polymerLegacy.html)(_templateObject_dd16da20f1e411e8a99f5dc819e27ed9()),is:"simple-search",properties:{alwaysFloatLabel:{type:Boolean,value:!1},caseSensitive:{type:Boolean,value:null},controls:{type:String,value:null},nextButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)"},nextButtonIcon:{type:String,value:"arrow-forward"},nextButtonLabel:{type:String,value:"next result"},noLabelFloat:{type:Boolean,value:!1},noResults:{type:Boolean,computed:"_hasNoResults(resultCount)"},noSearch:{type:Boolean,computed:"_hasNoSearch(searchTerms)"},prevButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)"},prevButtonIcon:{type:String,value:"arrow-back"},prevButtonLabel:{type:String,value:"previous result"},resultCount:{type:Number,value:0},resultPointer:{type:Number,value:0},resultsSpan:{type:String,computed:"_getResultsSpan(noSearch,resultPointer,resultCount)"},searchInputIcon:{type:String,value:"search"},searchInputLabel:{type:String,value:"search"},searchTerms:{type:Array,value:[]},target:{type:Object,value:null}},ready:function ready(){var root=this,search=root.$.input;root._getSearchText(search.value);root.addEventListener("change",function(e){root._getSearchText(search.value);root.resultCount=0;root.resultPointer=0;root.fire("search",root)});root.$.prev.addEventListener("tap",function(e){root._navigateResults(-1)});root.$.next.addEventListener("tap",function(e){root._navigateResults(1)})},_hasNoResults:function _hasNoResults(resultCount){return 1>resultCount},_hasNoSearch:function _hasNoSearch(searchTerms){return 1>searchTerms.length},_getResultsSpan:function _getResultsSpan(noSearch,resultPointer,resultCount){var html="";if(0<resultCount&&0<resultPointer){html=resultPointer+"/"+resultCount}else{html=" "+resultCount}this.$.xofy.innerHTML=html;return this.$.xofy.innerHTML},_navigateResults:function _navigateResults(increment){if(0<this.resultPointer+increment&&this.resultPointer+increment<=this.resultCount){this.resultPointer+=increment;this.fire("goto-result",this.resultPointer)}},_isNavButtonDisabled:function _isNavButtonDisabled(resultPointer,resultCount,resultsSpan,increment){return""==resultsSpan||0>=resultPointer+increment||resultPointer+increment>resultCount},_getSearchText:function _getSearchText(find){var temp=[];if(find!==void 0&&null!==find){temp=find.split(/[\"\']/gm);for(var i=0;i<temp.length;i++){temp[i]=temp[i].trim();if(""===temp[i])temp.splice(i,1)}}this.set("searchTerms",temp.slice(0))},findMatches:function findMatches(content){for(var root=this,terms=root.searchTerms,modifier=this.caseSensitive?"gm":"gim",results=content.slice(0),updateResults=function updateResults(find){for(var i=0;i<results.length;i++){if(!1===results[i].matched){var regex=new RegExp("\\b"+find+"\\b",modifier),text=results[i].text,start=text.search(regex),end=start+find.length;if(-1<start){root.resultCount+=1;var pre=text.slice(0,start),match=text.slice(start,end),post=text.slice(end,text.length),update=results.splice(i,1,{matched:!1,text:pre,searchObject:root},{matched:!0,matchNumber:root.resultCount,text:match,searchObject:root},{matched:!1,text:post,searchObject:root})}}}},i=0;i<terms.length;i++){updateResults(terms[i])}root.resultPointer=0;return results}})}); | ||
define(["exports","./node_modules/@polymer/polymer/polymer-element.js","./node_modules/@polymer/iron-icons/iron-icons.js","./node_modules/@polymer/paper-input/paper-input.js","./node_modules/@polymer/paper-tooltip/paper-tooltip.js","./lib/simple-search-content.js"],function(_exports,_polymerElement,_ironIcons,_paperInput,_paperTooltip,_simpleSearchContent){"use strict";Object.defineProperty(_exports,"__esModule",{value:!0});_exports.SimpleSearch=void 0;function _templateObject_1f338de0f51911e8bde2f7b1e37fe5b6(){var data=babelHelpers.taggedTemplateLiteral(["\n <style is=\"custom-style\">\n :host {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n width: 100%;\n }\n :host #input {\n flex-grow: 2;\n margin-right: 4px;\n --paper-input-container-input-color: var(--simple-search-input-text-color, #000);\n --paper-input-container-focus-color: var(--simple-search-input-line-color, #000);\n --paper-input-container-color: var(--simple-search-input-placeholder-color, #222);\n color: var(--simple-search-input-placeholder-color, #222);\n @apply --simple-search-container;\n }\n :host #xofy {\n margin: 8px;\n }\n :host button {\n margin: 8px 0 8px;\n color: var(--simple-search-button-color, #111);\n background-color: var(--simple-search-button-bg-color, #eee);\n border-color: var(--simple-search-button-border-color, #ccc);\n @apply --simple-search-button;\n }\n :host button:not([disabled]):focus,\n :host button:not([disabled]):hover {\n cursor: pointer;\n color: var(--simple-search-button-hover-color, #000);\n background-color: var(--simple-search-button-hover-bg-color, #fff);\n border-color: var(--simple-search-button-hover-border-color, #ddd);\n @apply --simple-search-button-hover;\n }\n :host button[disabled] {\n cursor: not-allowed;\n color: var(--simple-search-button-disabled-color, #999);\n background-color: var(--simple-search-button-disabled-bg-color, #eee);\n border-color: var(--simple-search-button-disabled-border-color, #ccc);\n @apply --simple-search-button-disabled;\n }\n :host button:not([controls]) {\n display: none;\n }\n :host [shrink-hide] {\n display: none;\n }\n </style>\n <paper-input id=\"input\" always-float-label$=\"[[alwaysFloatLabel]]\" label=\"[[searchInputLabel]]\" no-label-float$=\"[[noLabelFloat]]\" on-change=\"_handleChange\">\n <iron-icon icon=\"[[searchInputIcon]]\" slot=\"prefix\"></iron-icon>\n </paper-input>\n <div id=\"xofy\" shrink-hide$=\"[[noSearch]]\"></div>\n <div shrink-hide$=\"[[noResults]]\">\n <button id=\"prev\" aria-label=\"[[prevButtonLabel]]\" aria-role=\"button\" controls$=\"[[controls]]\" disabled$=\"[[prevButtonDisabled]]\" on-tap=\"_navigateResults\" tabindex=\"0\">\n <iron-icon icon=\"[[prevButtonIcon]]\"></iron-icon>\n </button>\n <paper-tooltip for=\"prev\">[[prevButtonLabel]]</paper-tooltip>\n <button id=\"next\" aria-label=\"[[nextButtonLabel]]\" aria-role=\"button\" controls$=\"[[controls]]\" disabled$=\"[[nextButtonDisabled]]\" on-tap=\"_navigateResults\" tabindex=\"0\">\n <iron-icon icon$=\"[[nextButtonIcon]]\"></iron-icon>\n </button>\n <paper-tooltip for=\"next\">[[nextButtonLabel]]</paper-tooltip>\n </div>"],["\n <style is=\"custom-style\">\n :host {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n width: 100%;\n }\n :host #input {\n flex-grow: 2;\n margin-right: 4px;\n --paper-input-container-input-color: var(--simple-search-input-text-color, #000);\n --paper-input-container-focus-color: var(--simple-search-input-line-color, #000);\n --paper-input-container-color: var(--simple-search-input-placeholder-color, #222);\n color: var(--simple-search-input-placeholder-color, #222);\n @apply --simple-search-container;\n }\n :host #xofy {\n margin: 8px;\n }\n :host button {\n margin: 8px 0 8px;\n color: var(--simple-search-button-color, #111);\n background-color: var(--simple-search-button-bg-color, #eee);\n border-color: var(--simple-search-button-border-color, #ccc);\n @apply --simple-search-button;\n }\n :host button:not([disabled]):focus,\n :host button:not([disabled]):hover {\n cursor: pointer;\n color: var(--simple-search-button-hover-color, #000);\n background-color: var(--simple-search-button-hover-bg-color, #fff);\n border-color: var(--simple-search-button-hover-border-color, #ddd);\n @apply --simple-search-button-hover;\n }\n :host button[disabled] {\n cursor: not-allowed;\n color: var(--simple-search-button-disabled-color, #999);\n background-color: var(--simple-search-button-disabled-bg-color, #eee);\n border-color: var(--simple-search-button-disabled-border-color, #ccc);\n @apply --simple-search-button-disabled;\n }\n :host button:not([controls]) {\n display: none;\n }\n :host [shrink-hide] {\n display: none;\n }\n </style>\n <paper-input id=\"input\" always-float-label\\$=\"[[alwaysFloatLabel]]\" label=\"[[searchInputLabel]]\" no-label-float\\$=\"[[noLabelFloat]]\" on-change=\"_handleChange\">\n <iron-icon icon=\"[[searchInputIcon]]\" slot=\"prefix\"></iron-icon>\n </paper-input>\n <div id=\"xofy\" shrink-hide\\$=\"[[noSearch]]\"></div>\n <div shrink-hide\\$=\"[[noResults]]\">\n <button id=\"prev\" aria-label=\"[[prevButtonLabel]]\" aria-role=\"button\" controls\\$=\"[[controls]]\" disabled\\$=\"[[prevButtonDisabled]]\" on-tap=\"_navigateResults\" tabindex=\"0\">\n <iron-icon icon=\"[[prevButtonIcon]]\"></iron-icon>\n </button>\n <paper-tooltip for=\"prev\">[[prevButtonLabel]]</paper-tooltip>\n <button id=\"next\" aria-label=\"[[nextButtonLabel]]\" aria-role=\"button\" controls\\$=\"[[controls]]\" disabled\\$=\"[[nextButtonDisabled]]\" on-tap=\"_navigateResults\" tabindex=\"0\">\n <iron-icon icon\\$=\"[[nextButtonIcon]]\"></iron-icon>\n </button>\n <paper-tooltip for=\"next\">[[nextButtonLabel]]</paper-tooltip>\n </div>"]);_templateObject_1f338de0f51911e8bde2f7b1e37fe5b6=function _templateObject_1f338de0f51911e8bde2f7b1e37fe5b6(){return data};return data}var SimpleSearch=function(_PolymerElement){babelHelpers.inherits(SimpleSearch,_PolymerElement);function SimpleSearch(){babelHelpers.classCallCheck(this,SimpleSearch);return babelHelpers.possibleConstructorReturn(this,babelHelpers.getPrototypeOf(SimpleSearch).apply(this,arguments))}babelHelpers.createClass(SimpleSearch,[{key:"ready",value:function ready(){babelHelpers.get(babelHelpers.getPrototypeOf(SimpleSearch.prototype),"ready",this).call(this);var root=this,search=root.$.input;root._getSearchText(search.value)}},{key:"_handleChange",value:function _handleChange(e){var root=this;root._getSearchText(root.$.input.value);root.resultCount=0;root.resultPointer=0;root.dispatchEvent(new CustomEvent("simple-search",{detail:{search:root,content:e}}))}},{key:"_hasNoResults",value:function _hasNoResults(resultCount){return 1>resultCount}},{key:"_hasNoSearch",value:function _hasNoSearch(searchTerms){return 1>searchTerms.length}},{key:"_getResultsSpan",value:function _getResultsSpan(noSearch,resultPointer,resultCount){var html="";if(0<resultCount&&0<resultPointer){html=resultPointer+"/"+resultCount}else{html=" "+resultCount}this.$.xofy.innerHTML=html;return this.$.xofy.innerHTML}},{key:"_navigateResults",value:function _navigateResults(e){var root=this,increment="next"===e.currentTarget.id?1:-1;if(0<this.resultPointer+increment&&this.resultPointer+increment<=this.resultCount){this.resultPointer+=increment;this.dispatchEvent(new CustomEvent("goto-result",{detail:this.resultPointer}))}}},{key:"_isNavButtonDisabled",value:function _isNavButtonDisabled(pointer,count,span,inc){return""==span||0>=pointer+inc||pointer+inc>count}},{key:"_getSearchText",value:function _getSearchText(find){var temp=[];if(find!==void 0&&null!==find){temp=find.split(/[\"\']/gm);for(var i=0;i<temp.length;i++){temp[i]=temp[i].trim();if(""===temp[i])temp.splice(i,1)}}this.set("searchTerms",[]);this.set("searchTerms",temp.slice(0))}},{key:"findMatches",value:function findMatches(content){for(var root=this,terms=root.searchTerms,modifier=this.caseSensitive?"gm":"gim",results=content.slice(0),updateResults=function updateResults(find){for(var i=0;i<results.length;i++){if(!1===results[i].matched){var regex=new RegExp("\\b"+find+"\\b",modifier),text=results[i].text,start=text.search(regex),end=start+find.length;if(-1<start){root.resultCount+=1;var pre=text.slice(0,start),match=text.slice(start,end),post=text.slice(end,text.length),update=results.splice(i,1,{matched:!1,text:pre,searchObject:root},{matched:!0,matchNumber:root.resultCount,text:match,searchObject:root},{matched:!1,text:post,searchObject:root})}}}},i=0;i<terms.length;i++){updateResults(terms[i])}root.resultPointer=0;return results}}],[{key:"is",get:function get(){return"simple-search"}},{key:"properties",get:function get(){return{alwaysFloatLabel:{type:Boolean,value:!1},caseSensitive:{type:Boolean,value:null},controls:{type:String,value:null},nextButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)"},nextButtonIcon:{type:String,value:"arrow-forward"},nextButtonLabel:{type:String,value:"next result"},noLabelFloat:{type:Boolean,value:!1},noResults:{type:Boolean,computed:"_hasNoResults(resultCount)"},noSearch:{type:Boolean,computed:"_hasNoSearch(searchTerms)"},prevButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)"},prevButtonIcon:{type:String,value:"arrow-back"},prevButtonLabel:{type:String,value:"previous result"},resultCount:{type:Number,value:0},resultPointer:{type:Number,value:0},resultsSpan:{type:String,computed:"_getResultsSpan(noSearch,resultPointer,resultCount)"},searchInputIcon:{type:String,value:"search"},searchInputLabel:{type:String,value:"search"},searchTerms:{type:Array,value:[]},target:{type:Object,value:null}}}},{key:"template",get:function get(){return(0,_polymerElement.html)(_templateObject_1f338de0f51911e8bde2f7b1e37fe5b6())}}]);return SimpleSearch}(_polymerElement.PolymerElement);_exports.SimpleSearch=SimpleSearch;customElements.define(SimpleSearch.is,SimpleSearch)}); |
@@ -1,66 +0,63 @@ | ||
import{html,Polymer}from"./node_modules/@polymer/polymer/polymer-legacy.js";import"./node_modules/@polymer/iron-icons/iron-icons.js";import"./node_modules/@polymer/paper-input/paper-input.js";import"./node_modules/@polymer/paper-tooltip/paper-tooltip.js";import"./lib/simple-search-content.js";Polymer({_template:html` | ||
<custom-style> | ||
<style is="custom-style"> | ||
:host { | ||
display: flex; | ||
align-items: flex-end; | ||
justify-content: space-between; | ||
width: 100%; | ||
} | ||
:host #input { | ||
flex-grow: 2; | ||
margin-right: 4px; | ||
--paper-input-container-input-color: var(--simple-search-input-text-color, #000); | ||
--paper-input-container-focus-color: var(--simple-search-input-line-color, #000); | ||
--paper-input-container-color: var(--simple-search-input-placeholder-color, #222); | ||
color: var(--simple-search-input-placeholder-color, #222); | ||
@apply --simple-search-container; | ||
} | ||
:host #xofy { | ||
margin: 8px; | ||
} | ||
:host button { | ||
margin: 8px 0 8px; | ||
color: var(--simple-search-button-color, #111); | ||
background-color: var(--simple-search-button-bg-color, #eee); | ||
border-color: var(--simple-search-button-border-color, #ccc); | ||
@apply --simple-search-button; | ||
} | ||
:host button:not([disabled]):focus, | ||
:host button:not([disabled]):hover { | ||
cursor: pointer; | ||
color: var(--simple-search-button-hover-color, #000); | ||
background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
@apply --simple-search-button-hover; | ||
} | ||
:host button[disabled] { | ||
cursor: not-allowed; | ||
color: var(--simple-search-button-disabled-color, #999); | ||
background-color: var(--simple-search-button-disabled-bg-color, #eee); | ||
border-color: var(--simple-search-button-disabled-border-color, #ccc); | ||
@apply --simple-search-button-disabled; | ||
} | ||
:host button:not([controls]) { | ||
display: none; | ||
} | ||
:host [shrink-hide] { | ||
display: none; | ||
} | ||
</style> | ||
</custom-style> | ||
<paper-input id="input" always-float-label\$="[[alwaysFloatLabel]]" label="[[searchInputLabel]]" no-label-float\$="[[noLabelFloat]]"> | ||
<iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon> | ||
</paper-input> | ||
<div id="xofy" shrink-hide\$="[[noSearch]]"></div> | ||
<div shrink-hide\$="[[noResults]]"> | ||
<button id="prev" aria-label="[[prevButtonLabel]]" aria-role="button" controls\$="[[controls]]" disabled\$="[[prevButtonDisabled]]" tabindex="0"> | ||
<iron-icon icon="[[prevButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip> | ||
<button id="next" aria-label="[[nextButtonLabel]]" aria-role="button" controls\$="[[controls]]" disabled\$="[[nextButtonDisabled]]" tabindex="0"> | ||
<iron-icon icon\$="[[nextButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip> | ||
</div> | ||
`,is:"simple-search",properties:{alwaysFloatLabel:{type:Boolean,value:!1},caseSensitive:{type:Boolean,value:null},controls:{type:String,value:null},nextButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)"},nextButtonIcon:{type:String,value:"arrow-forward"},nextButtonLabel:{type:String,value:"next result"},noLabelFloat:{type:Boolean,value:!1},noResults:{type:Boolean,computed:"_hasNoResults(resultCount)"},noSearch:{type:Boolean,computed:"_hasNoSearch(searchTerms)"},prevButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)"},prevButtonIcon:{type:String,value:"arrow-back"},prevButtonLabel:{type:String,value:"previous result"},resultCount:{type:Number,value:0},resultPointer:{type:Number,value:0},resultsSpan:{type:String,computed:"_getResultsSpan(noSearch,resultPointer,resultCount)"},searchInputIcon:{type:String,value:"search"},searchInputLabel:{type:String,value:"search"},searchTerms:{type:Array,value:[]},target:{type:Object,value:null}},ready:function(){let root=this,search=root.$.input;root._getSearchText(search.value);root.addEventListener("change",function(e){root._getSearchText(search.value);root.resultCount=0;root.resultPointer=0;root.fire("search",root)});root.$.prev.addEventListener("tap",function(e){root._navigateResults(-1)});root.$.next.addEventListener("tap",function(e){root._navigateResults(1)})},_hasNoResults:function(resultCount){return 1>resultCount},_hasNoSearch:function(searchTerms){return 1>searchTerms.length},_getResultsSpan:function(noSearch,resultPointer,resultCount){let html="";if(0<resultCount&&0<resultPointer){html=resultPointer+"/"+resultCount}else{html=" "+resultCount}this.$.xofy.innerHTML=html;return this.$.xofy.innerHTML},_navigateResults:function(increment){if(0<this.resultPointer+increment&&this.resultPointer+increment<=this.resultCount){this.resultPointer+=increment;this.fire("goto-result",this.resultPointer)}},_isNavButtonDisabled:function(resultPointer,resultCount,resultsSpan,increment){return""==resultsSpan||0>=resultPointer+increment||resultPointer+increment>resultCount},_getSearchText:function(find){let temp=[];if(find!==void 0&&null!==find){temp=find.split(/[\"\']/gm);for(let i=0;i<temp.length;i++){temp[i]=temp[i].trim();if(""===temp[i])temp.splice(i,1)}}this.set("searchTerms",temp.slice(0))},findMatches:function(content){let root=this,terms=root.searchTerms,modifier=this.caseSensitive?"gm":"gim",results=content.slice(0),updateResults=function(find){for(let i=0;i<results.length;i++){if(!1===results[i].matched){let regex=new RegExp("\\b"+find+"\\b",modifier),text=results[i].text,start=text.search(regex),end=start+find.length;if(-1<start){root.resultCount+=1;let pre=text.slice(0,start),match=text.slice(start,end),post=text.slice(end,text.length),update=results.splice(i,1,{matched:!1,text:pre,searchObject:root},{matched:!0,matchNumber:root.resultCount,text:match,searchObject:root},{matched:!1,text:post,searchObject:root})}}}};for(let i=0;i<terms.length;i++){updateResults(terms[i])}root.resultPointer=0;return results}}); | ||
import{html,PolymerElement}from"./node_modules/@polymer/polymer/polymer-element.js";import"./node_modules/@polymer/iron-icons/iron-icons.js";import"./node_modules/@polymer/paper-input/paper-input.js";import"./node_modules/@polymer/paper-tooltip/paper-tooltip.js";import"./lib/simple-search-content.js";export{SimpleSearch};class SimpleSearch extends PolymerElement{static get is(){return"simple-search"}static get properties(){return{alwaysFloatLabel:{type:Boolean,value:!1},caseSensitive:{type:Boolean,value:null},controls:{type:String,value:null},nextButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)"},nextButtonIcon:{type:String,value:"arrow-forward"},nextButtonLabel:{type:String,value:"next result"},noLabelFloat:{type:Boolean,value:!1},noResults:{type:Boolean,computed:"_hasNoResults(resultCount)"},noSearch:{type:Boolean,computed:"_hasNoSearch(searchTerms)"},prevButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)"},prevButtonIcon:{type:String,value:"arrow-back"},prevButtonLabel:{type:String,value:"previous result"},resultCount:{type:Number,value:0},resultPointer:{type:Number,value:0},resultsSpan:{type:String,computed:"_getResultsSpan(noSearch,resultPointer,resultCount)"},searchInputIcon:{type:String,value:"search"},searchInputLabel:{type:String,value:"search"},searchTerms:{type:Array,value:[]},target:{type:Object,value:null}}}static get template(){return html` | ||
<style is="custom-style"> | ||
:host { | ||
display: flex; | ||
align-items: flex-end; | ||
justify-content: space-between; | ||
width: 100%; | ||
} | ||
:host #input { | ||
flex-grow: 2; | ||
margin-right: 4px; | ||
--paper-input-container-input-color: var(--simple-search-input-text-color, #000); | ||
--paper-input-container-focus-color: var(--simple-search-input-line-color, #000); | ||
--paper-input-container-color: var(--simple-search-input-placeholder-color, #222); | ||
color: var(--simple-search-input-placeholder-color, #222); | ||
@apply --simple-search-container; | ||
} | ||
:host #xofy { | ||
margin: 8px; | ||
} | ||
:host button { | ||
margin: 8px 0 8px; | ||
color: var(--simple-search-button-color, #111); | ||
background-color: var(--simple-search-button-bg-color, #eee); | ||
border-color: var(--simple-search-button-border-color, #ccc); | ||
@apply --simple-search-button; | ||
} | ||
:host button:not([disabled]):focus, | ||
:host button:not([disabled]):hover { | ||
cursor: pointer; | ||
color: var(--simple-search-button-hover-color, #000); | ||
background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
@apply --simple-search-button-hover; | ||
} | ||
:host button[disabled] { | ||
cursor: not-allowed; | ||
color: var(--simple-search-button-disabled-color, #999); | ||
background-color: var(--simple-search-button-disabled-bg-color, #eee); | ||
border-color: var(--simple-search-button-disabled-border-color, #ccc); | ||
@apply --simple-search-button-disabled; | ||
} | ||
:host button:not([controls]) { | ||
display: none; | ||
} | ||
:host [shrink-hide] { | ||
display: none; | ||
} | ||
</style> | ||
<paper-input id="input" always-float-label\$="[[alwaysFloatLabel]]" label="[[searchInputLabel]]" no-label-float\$="[[noLabelFloat]]" on-change="_handleChange"> | ||
<iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon> | ||
</paper-input> | ||
<div id="xofy" shrink-hide\$="[[noSearch]]"></div> | ||
<div shrink-hide\$="[[noResults]]"> | ||
<button id="prev" aria-label="[[prevButtonLabel]]" aria-role="button" controls\$="[[controls]]" disabled\$="[[prevButtonDisabled]]" on-tap="_navigateResults" tabindex="0"> | ||
<iron-icon icon="[[prevButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip> | ||
<button id="next" aria-label="[[nextButtonLabel]]" aria-role="button" controls\$="[[controls]]" disabled\$="[[nextButtonDisabled]]" on-tap="_navigateResults" tabindex="0"> | ||
<iron-icon icon\$="[[nextButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip> | ||
</div>`}ready(){super.ready();let root=this,search=root.$.input;root._getSearchText(search.value)}_handleChange(e){let root=this;root._getSearchText(root.$.input.value);root.resultCount=0;root.resultPointer=0;root.dispatchEvent(new CustomEvent("simple-search",{detail:{search:root,content:e}}))}_hasNoResults(resultCount){return 1>resultCount}_hasNoSearch(searchTerms){return 1>searchTerms.length}_getResultsSpan(noSearch,resultPointer,resultCount){let html="";if(0<resultCount&&0<resultPointer){html=resultPointer+"/"+resultCount}else{html=" "+resultCount}this.$.xofy.innerHTML=html;return this.$.xofy.innerHTML}_navigateResults(e){let root=this,increment="next"===e.currentTarget.id?1:-1;if(0<this.resultPointer+increment&&this.resultPointer+increment<=this.resultCount){this.resultPointer+=increment;this.dispatchEvent(new CustomEvent("goto-result",{detail:this.resultPointer}))}}_isNavButtonDisabled(pointer,count,span,inc){return""==span||0>=pointer+inc||pointer+inc>count}_getSearchText(find){let temp=[];if(find!==void 0&&null!==find){temp=find.split(/[\"\']/gm);for(let i=0;i<temp.length;i++){temp[i]=temp[i].trim();if(""===temp[i])temp.splice(i,1)}}this.set("searchTerms",[]);this.set("searchTerms",temp.slice(0))}findMatches(content){let root=this,terms=root.searchTerms,modifier=this.caseSensitive?"gm":"gim",results=content.slice(0),updateResults=function(find){for(let i=0;i<results.length;i++){if(!1===results[i].matched){let regex=new RegExp("\\b"+find+"\\b",modifier),text=results[i].text,start=text.search(regex),end=start+find.length;if(-1<start){root.resultCount+=1;let pre=text.slice(0,start),match=text.slice(start,end),post=text.slice(end,text.length),update=results.splice(i,1,{matched:!1,text:pre,searchObject:root},{matched:!0,matchNumber:root.resultCount,text:match,searchObject:root},{matched:!1,text:post,searchObject:root})}}}};for(let i=0;i<terms.length;i++){updateResults(terms[i])}root.resultPointer=0;return results}}customElements.define(SimpleSearch.is,SimpleSearch); |
@@ -1,2 +0,6 @@ | ||
import { html, Polymer } from "@polymer/polymer/polymer-legacy.js"; | ||
/** | ||
* Copyright 2018 The Pennsylvania State University | ||
* @license Apache-2.0, see License.md for full text. | ||
*/ | ||
import { html, PolymerElement } from "@polymer/polymer/polymer-element.js"; | ||
import "@polymer/iron-icons/iron-icons.js"; | ||
@@ -6,302 +10,335 @@ import "@polymer/paper-input/paper-input.js"; | ||
import "./lib/simple-search-content.js"; | ||
export { SimpleSearch }; | ||
/** | ||
`simple-search` | ||
A button used in simple-search | ||
* `simple-search` | ||
* `A button used in simple-search` | ||
* | ||
* | ||
* @microcopy - the mental model for this element | ||
* | ||
* ```<simple-search | ||
* case-sensitive$="[[caseSensitive]]" // is search case sensitive? | ||
* controls$="[[controls]]"> | ||
* </simple-search>``` | ||
* | ||
* The searchTerms property provides an array of search terms entered in to the input. | ||
* The findMatches function returns an array of parsed results. | ||
* For example if I searched for the with | ||
* `findMatches("The quick brown fox jumps over the lazy dog.")`, | ||
* the array would be: | ||
* ``[ | ||
* { | ||
* "matched": true, | ||
* "matchNumber": 1, | ||
* "text": "The" | ||
* },{ | ||
* "matched": false, | ||
* "text": " quick brown fox jumps over " | ||
* },{ | ||
* "matched": true, | ||
* "matchNumber": 2, | ||
* "text": "the" | ||
* },{ | ||
* "matched": false, | ||
* "text": " lazy dog." | ||
* } | ||
* ]``` | ||
* or `findMatches("The quick brown fox jumps over the lazy dog.",true)`, | ||
* the array would be: | ||
* ```[ | ||
* { | ||
* "matched": false, | ||
* "text": "The quick brown fox jumps over " | ||
* },{ | ||
* "matched": true, | ||
* "matchNumber": 1, | ||
* "text": "the" | ||
* },{ | ||
* "matched": false, | ||
* "text": " lazy dog." | ||
* } | ||
* ]``` | ||
* | ||
* CSS Variables: | ||
* For the input field... | ||
* ```--paper-input-container-input-color: var(--simple-search-input-color, #111); | ||
* --paper-input-container-focus-color: var(--simple-search-input-placeholder-color, #000); | ||
* --paper-input-container-color: var(--simple-search-input-line-color, #fff); | ||
* @apply --simple-search-container;``` | ||
* | ||
* For buttons: | ||
* ```color: var(--simple-search-button-color, #111); | ||
* background-color: var(--simple-search-button-bg-color, #eee); | ||
* border-color: var(--simple-search-button-border-color, #ccc); | ||
* @apply --simple-search-button;` | ||
* | ||
* For buttons on hover: | ||
* ```color: var(--simple-search-button-hover-color, #000); | ||
* background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
* border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
* @apply --simple-search-button-hover;``` | ||
* | ||
* For disabled buttons: | ||
* ```color: var(--simple-search-button-disabled-color, #666); | ||
* background-color: var(--simple-search-button-disabled-bg-color, #ccc); | ||
* border-color: var(--simple-search-button-disabled-border-color, #aaa); | ||
* @apply --simple-search-button-disabled;``` | ||
* | ||
* @polymer | ||
* @customElement | ||
* @demo demo/index.html | ||
* | ||
*/ | ||
class SimpleSearch extends PolymerElement { | ||
static get is() { | ||
return "simple-search"; | ||
} | ||
@demo demo/index.html | ||
static get properties() { | ||
return { | ||
/** | ||
* always float the label | ||
*/ | ||
alwaysFloatLabel: { | ||
type: Boolean, | ||
value: false | ||
}, | ||
/** | ||
* Is the search case-sensitive | ||
*/ | ||
caseSensitive: { | ||
type: Boolean, | ||
value: null | ||
}, | ||
/** | ||
* The id of the container element that the navigation buttons control | ||
*/ | ||
controls: { | ||
type: String, | ||
value: null | ||
}, | ||
/** | ||
* is the previous next button disabled | ||
*/ | ||
nextButtonDisabled: { | ||
type: Boolean, | ||
computed: | ||
"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)" | ||
}, | ||
/** | ||
* label for next result icon | ||
*/ | ||
nextButtonIcon: { | ||
type: String, | ||
value: "arrow-forward" | ||
}, | ||
/** | ||
* label for next result button | ||
*/ | ||
nextButtonLabel: { | ||
type: String, | ||
value: "next result" | ||
}, | ||
/** | ||
* never float the label | ||
*/ | ||
noLabelFloat: { | ||
type: Boolean, | ||
value: false | ||
}, | ||
/** | ||
* are there any results to navigate? | ||
*/ | ||
noResults: { | ||
type: Boolean, | ||
computed: "_hasNoResults(resultCount)" | ||
}, | ||
/** | ||
* is there an active search? | ||
*/ | ||
noSearch: { | ||
type: Boolean, | ||
computed: "_hasNoSearch(searchTerms)" | ||
}, | ||
/** | ||
* is the previous result button disabled | ||
*/ | ||
prevButtonDisabled: { | ||
type: Boolean, | ||
computed: | ||
"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)" | ||
}, | ||
/** | ||
* label for previous result icon | ||
*/ | ||
prevButtonIcon: { | ||
type: String, | ||
value: "arrow-back" | ||
}, | ||
/** | ||
* label for previous result button | ||
*/ | ||
prevButtonLabel: { | ||
type: String, | ||
value: "previous result" | ||
}, | ||
/** | ||
* Number of results. | ||
*/ | ||
@microcopy - the mental model for this element | ||
<simple-search | ||
case-sensitive$="[[caseSensitive]]" // is search case sensitive? | ||
controls$="[[controls]]" | ||
> | ||
</simple-search> | ||
The searchTerms property provides an array of search terms entered in to the input. | ||
The findMatches function returns an array of parsed results. | ||
For example if I searched for the with | ||
findMatches("The quick brown fox jumps over the lazy dog."), | ||
the array would be: | ||
[ | ||
{ | ||
"matched": true, | ||
"matchNumber": 1, | ||
"text": "The" | ||
},{ | ||
"matched": false, | ||
"text": " quick brown fox jumps over " | ||
},{ | ||
"matched": true, | ||
"matchNumber": 2, | ||
"text": "the" | ||
},{ | ||
"matched": false, | ||
"text": " lazy dog." | ||
} | ||
] | ||
or findMatches("The quick brown fox jumps over the lazy dog.",true), | ||
the array would be: | ||
[ | ||
{ | ||
"matched": false, | ||
"text": "The quick brown fox jumps over " | ||
},{ | ||
"matched": true, | ||
"matchNumber": 1, | ||
"text": "the" | ||
},{ | ||
"matched": false, | ||
"text": " lazy dog." | ||
} | ||
] | ||
CSS Variables: | ||
For the input field... | ||
--paper-input-container-input-color: var(--simple-search-input-color, #111); | ||
--paper-input-container-focus-color: var(--simple-search-input-placeholder-color, #000); | ||
--paper-input-container-color: var(--simple-search-input-line-color, #fff); | ||
@apply --simple-search-container; | ||
For buttons: | ||
color: var(--simple-search-button-color, #111); | ||
background-color: var(--simple-search-button-bg-color, #eee); | ||
border-color: var(--simple-search-button-border-color, #ccc); | ||
@apply --simple-search-button; | ||
For buttons on hover: | ||
color: var(--simple-search-button-hover-color, #000); | ||
background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
@apply --simple-search-button-hover; | ||
For disabled buttons: | ||
color: var(--simple-search-button-disabled-color, #666); | ||
background-color: var(--simple-search-button-disabled-bg-color, #ccc); | ||
border-color: var(--simple-search-button-disabled-border-color, #aaa); | ||
@apply --simple-search-button-disabled; | ||
*/ | ||
Polymer({ | ||
_template: html` | ||
<custom-style> | ||
<style is="custom-style"> | ||
:host { | ||
display: flex; | ||
align-items: flex-end; | ||
justify-content: space-between; | ||
width: 100%; | ||
resultCount: { | ||
type: Number, | ||
value: 0 | ||
}, | ||
/** | ||
* Which result are we currently on? | ||
*/ | ||
resultPointer: { | ||
type: Number, | ||
value: 0 | ||
}, | ||
/** | ||
* Number of results. | ||
*/ | ||
resultsSpan: { | ||
type: String, | ||
computed: "_getResultsSpan(noSearch,resultPointer,resultCount)" | ||
}, | ||
/** | ||
* label for search icon | ||
*/ | ||
searchInputIcon: { | ||
type: String, | ||
value: "search" | ||
}, | ||
/** | ||
* label for search input | ||
*/ | ||
searchInputLabel: { | ||
type: String, | ||
value: "search" | ||
}, | ||
/** | ||
* an array of search terms | ||
*/ | ||
searchTerms: { | ||
type: Array, | ||
value: [] | ||
}, | ||
/** | ||
* The container element that the navigation buttons control | ||
*/ | ||
target: { | ||
type: Object, | ||
value: null | ||
} | ||
:host #input { | ||
flex-grow: 2; | ||
margin-right: 4px; | ||
--paper-input-container-input-color: var(--simple-search-input-text-color, #000); | ||
--paper-input-container-focus-color: var(--simple-search-input-line-color, #000); | ||
--paper-input-container-color: var(--simple-search-input-placeholder-color, #222); | ||
color: var(--simple-search-input-placeholder-color, #222); | ||
@apply --simple-search-container; | ||
} | ||
:host #xofy { | ||
margin: 8px; | ||
} | ||
:host button { | ||
margin: 8px 0 8px; | ||
color: var(--simple-search-button-color, #111); | ||
background-color: var(--simple-search-button-bg-color, #eee); | ||
border-color: var(--simple-search-button-border-color, #ccc); | ||
@apply --simple-search-button; | ||
} | ||
:host button:not([disabled]):focus, | ||
:host button:not([disabled]):hover { | ||
cursor: pointer; | ||
color: var(--simple-search-button-hover-color, #000); | ||
background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
@apply --simple-search-button-hover; | ||
} | ||
:host button[disabled] { | ||
cursor: not-allowed; | ||
color: var(--simple-search-button-disabled-color, #999); | ||
background-color: var(--simple-search-button-disabled-bg-color, #eee); | ||
border-color: var(--simple-search-button-disabled-border-color, #ccc); | ||
@apply --simple-search-button-disabled; | ||
} | ||
:host button:not([controls]) { | ||
display: none; | ||
} | ||
:host [shrink-hide] { | ||
display: none; | ||
} | ||
</style> | ||
</custom-style> | ||
<paper-input id="input" always-float-label\$="[[alwaysFloatLabel]]" label="[[searchInputLabel]]" no-label-float\$="[[noLabelFloat]]"> | ||
<iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon> | ||
</paper-input> | ||
<div id="xofy" shrink-hide\$="[[noSearch]]"></div> | ||
<div shrink-hide\$="[[noResults]]"> | ||
<button id="prev" aria-label="[[prevButtonLabel]]" aria-role="button" controls\$="[[controls]]" disabled\$="[[prevButtonDisabled]]" tabindex="0"> | ||
<iron-icon icon="[[prevButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip> | ||
<button id="next" aria-label="[[nextButtonLabel]]" aria-role="button" controls\$="[[controls]]" disabled\$="[[nextButtonDisabled]]" tabindex="0"> | ||
<iron-icon icon\$="[[nextButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip> | ||
</div> | ||
`, | ||
}; | ||
} | ||
is: "simple-search", | ||
// render function | ||
static get template() { | ||
return html` | ||
<style is="custom-style"> | ||
:host { | ||
display: flex; | ||
align-items: flex-end; | ||
justify-content: space-between; | ||
width: 100%; | ||
} | ||
:host #input { | ||
flex-grow: 2; | ||
margin-right: 4px; | ||
--paper-input-container-input-color: var( | ||
--simple-search-input-text-color, | ||
#000 | ||
); | ||
--paper-input-container-focus-color: var( | ||
--simple-search-input-line-color, | ||
#000 | ||
); | ||
--paper-input-container-color: var( | ||
--simple-search-input-placeholder-color, | ||
#222 | ||
); | ||
color: var(--simple-search-input-placeholder-color, #222); | ||
@apply --simple-search-container; | ||
} | ||
:host #xofy { | ||
margin: 8px; | ||
} | ||
:host button { | ||
margin: 8px 0 8px; | ||
color: var(--simple-search-button-color, #111); | ||
background-color: var(--simple-search-button-bg-color, #eee); | ||
border-color: var(--simple-search-button-border-color, #ccc); | ||
@apply --simple-search-button; | ||
} | ||
:host button:not([disabled]):focus, | ||
:host button:not([disabled]):hover { | ||
cursor: pointer; | ||
color: var(--simple-search-button-hover-color, #000); | ||
background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
@apply --simple-search-button-hover; | ||
} | ||
:host button[disabled] { | ||
cursor: not-allowed; | ||
color: var(--simple-search-button-disabled-color, #999); | ||
background-color: var(--simple-search-button-disabled-bg-color, #eee); | ||
border-color: var(--simple-search-button-disabled-border-color, #ccc); | ||
@apply --simple-search-button-disabled; | ||
} | ||
:host button:not([controls]) { | ||
display: none; | ||
} | ||
:host [shrink-hide] { | ||
display: none; | ||
} | ||
</style> | ||
<paper-input | ||
id="input" | ||
always-float-label\$="[[alwaysFloatLabel]]" | ||
label="[[searchInputLabel]]" | ||
no-label-float\$="[[noLabelFloat]]" | ||
on-change="_handleChange" | ||
> | ||
<iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon> | ||
</paper-input> | ||
<div id="xofy" shrink-hide\$="[[noSearch]]"></div> | ||
<div shrink-hide\$="[[noResults]]"> | ||
<button | ||
id="prev" | ||
aria-label="[[prevButtonLabel]]" | ||
aria-role="button" | ||
controls\$="[[controls]]" | ||
disabled\$="[[prevButtonDisabled]]" | ||
on-tap="_navigateResults" | ||
tabindex="0" | ||
> | ||
<iron-icon icon="[[prevButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip> | ||
<button | ||
id="next" | ||
aria-label="[[nextButtonLabel]]" | ||
aria-role="button" | ||
controls\$="[[controls]]" | ||
disabled\$="[[nextButtonDisabled]]" | ||
on-tap="_navigateResults" | ||
tabindex="0" | ||
> | ||
<iron-icon icon\$="[[nextButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip> | ||
</div> | ||
`; | ||
} | ||
properties: { | ||
/** | ||
* always float the label | ||
*/ | ||
alwaysFloatLabel: { | ||
type: Boolean, | ||
value: false | ||
}, | ||
/** | ||
* Is the search case-sensitive | ||
*/ | ||
caseSensitive: { | ||
type: Boolean, | ||
value: null | ||
}, | ||
/** | ||
* The id of the container element that the navigation buttons control | ||
*/ | ||
controls: { | ||
type: String, | ||
value: null | ||
}, | ||
/** | ||
* is the previous next button disabled | ||
*/ | ||
nextButtonDisabled: { | ||
type: Boolean, | ||
computed: "_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)" | ||
}, | ||
/** | ||
* label for next result icon | ||
*/ | ||
nextButtonIcon: { | ||
type: String, | ||
value: "arrow-forward" | ||
}, | ||
/** | ||
* label for next result button | ||
*/ | ||
nextButtonLabel: { | ||
type: String, | ||
value: "next result" | ||
}, | ||
/** | ||
* never float the label | ||
*/ | ||
noLabelFloat: { | ||
type: Boolean, | ||
value: false | ||
}, | ||
/** | ||
* are there any results to navigate? | ||
*/ | ||
noResults: { | ||
type: Boolean, | ||
computed: "_hasNoResults(resultCount)" | ||
}, | ||
/** | ||
* is there an active search? | ||
*/ | ||
noSearch: { | ||
type: Boolean, | ||
computed: "_hasNoSearch(searchTerms)" | ||
}, | ||
/** | ||
* is the previous result button disabled | ||
*/ | ||
prevButtonDisabled: { | ||
type: Boolean, | ||
computed: "_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)" | ||
}, | ||
/** | ||
* label for previous result icon | ||
*/ | ||
prevButtonIcon: { | ||
type: String, | ||
value: "arrow-back" | ||
}, | ||
/** | ||
* label for previous result button | ||
*/ | ||
prevButtonLabel: { | ||
type: String, | ||
value: "previous result" | ||
}, | ||
/** | ||
* Number of results. | ||
*/ | ||
resultCount: { | ||
type: Number, | ||
value: 0 | ||
}, | ||
/** | ||
* Which result are we currently on? | ||
*/ | ||
resultPointer: { | ||
type: Number, | ||
value: 0 | ||
}, | ||
/** | ||
* Number of results. | ||
*/ | ||
resultsSpan: { | ||
type: String, | ||
computed: "_getResultsSpan(noSearch,resultPointer,resultCount)" | ||
}, | ||
/** | ||
* label for search icon | ||
*/ | ||
searchInputIcon: { | ||
type: String, | ||
value: "search" | ||
}, | ||
/** | ||
* label for search input | ||
*/ | ||
searchInputLabel: { | ||
type: String, | ||
value: "search" | ||
}, | ||
/** | ||
* an array of search terms | ||
*/ | ||
searchTerms: { | ||
type: Array, | ||
value: [] | ||
}, | ||
/** | ||
* The container element that the navigation buttons control | ||
*/ | ||
target: { | ||
type: Object, | ||
value: null | ||
} | ||
}, | ||
ready: function() { | ||
ready() { | ||
super.ready(); | ||
let root = this, | ||
search = root.$.input; | ||
root._getSearchText(search.value); | ||
root.addEventListener("change", function(e) { | ||
root._getSearchText(search.value); | ||
root.resultCount = 0; | ||
root.resultPointer = 0; | ||
root.fire("search", root); | ||
}); | ||
root.$.prev.addEventListener("tap", function(e) { | ||
root._navigateResults(-1); | ||
}); | ||
root.$.next.addEventListener("tap", function(e) { | ||
root._navigateResults(1); | ||
}); | ||
}, | ||
} | ||
@@ -311,17 +348,41 @@ /** | ||
*/ | ||
_hasNoResults: function(resultCount) { | ||
_handleChange(e) { | ||
let root = this; | ||
root._getSearchText(root.$.input.value); | ||
root.resultCount = 0; | ||
root.resultPointer = 0; | ||
root.dispatchEvent( | ||
new CustomEvent("simple-search", { detail: { search: root, content: e } }) | ||
); | ||
} | ||
/** | ||
* are there any results to navigate? | ||
* | ||
* @param {number} total number of results | ||
* @returns {boolean} whether or not there are results | ||
*/ | ||
_hasNoResults(resultCount) { | ||
return resultCount < 1; | ||
}, | ||
} | ||
/** | ||
* are there any results to navigate? | ||
* | ||
* @param {array} array of search terms | ||
* @returns {boolean} whether or not there are search terms | ||
*/ | ||
_hasNoSearch: function(searchTerms) { | ||
_hasNoSearch(searchTerms) { | ||
return searchTerms.length < 1; | ||
}, | ||
} | ||
/** | ||
* get results span text | ||
* | ||
* @param {boolean} whether or not there are search terms | ||
* @param {number} the current search result's position | ||
* @param {number} the total number of search results | ||
* @returns {string} "y results" or "x/y" text | ||
*/ | ||
_getResultsSpan: function(noSearch, resultPointer, resultCount) { | ||
_getResultsSpan(noSearch, resultPointer, resultCount) { | ||
let html = ""; | ||
@@ -335,3 +396,3 @@ if (resultCount > 0 && resultPointer > 0) { | ||
return this.$.xofy.innerHTML; | ||
}, | ||
} | ||
@@ -341,3 +402,5 @@ /** | ||
*/ | ||
_navigateResults: function(increment) { | ||
_navigateResults(e) { | ||
let root = this, | ||
increment = e.currentTarget.id === "next" ? 1 : -1; | ||
if ( | ||
@@ -348,5 +411,7 @@ this.resultPointer + increment > 0 && | ||
this.resultPointer += increment; | ||
this.fire("goto-result", this.resultPointer); | ||
this.dispatchEvent( | ||
new CustomEvent("goto-result", { detail: this.resultPointer }) | ||
); | ||
} | ||
}, | ||
} | ||
@@ -356,19 +421,12 @@ /** | ||
*/ | ||
_isNavButtonDisabled: function( | ||
resultPointer, | ||
resultCount, | ||
resultsSpan, | ||
increment | ||
) { | ||
return ( | ||
resultsSpan == "" || | ||
resultPointer + increment <= 0 || | ||
resultPointer + increment > resultCount | ||
); | ||
}, | ||
_isNavButtonDisabled(pointer, count, span, inc) { | ||
return span == "" || pointer + inc <= 0 || pointer + inc > count; | ||
} | ||
/** | ||
* gets the tab-index of cues based on whether or not interactive cues are disabled | ||
* | ||
* @param {string} a string of search text | ||
*/ | ||
_getSearchText: function(find) { | ||
_getSearchText(find) { | ||
let temp = new Array(); | ||
@@ -382,4 +440,5 @@ if (find !== undefined && find !== null) { | ||
} | ||
this.set("searchTerms", []); | ||
this.set("searchTerms", temp.slice(0)); | ||
}, | ||
} | ||
@@ -389,5 +448,5 @@ /** | ||
* For example if I searched for the with | ||
* findMatches("The quick brown fox jumps over the lazy dog."), | ||
* `findMatches("The quick brown fox jumps over the lazy dog.")`, | ||
* the array would be: | ||
* [ | ||
* ```[ | ||
* { | ||
@@ -412,7 +471,7 @@ * "matched": true, | ||
* } | ||
* ] | ||
* ]``` | ||
* | ||
* or findMatches("The quick brown fox jumps over the lazy dog.",true), | ||
* or `findMatches("The quick brown fox jumps over the lazy dog.",true)`, | ||
* the array would be: | ||
* [ | ||
* ```[ | ||
* { | ||
@@ -432,5 +491,8 @@ * "matched": false, | ||
* } | ||
* ] | ||
* ]``` | ||
* | ||
* @param {array} an array of search terms | ||
* @returns {array} an array of search results | ||
*/ | ||
findMatches: function(content) { | ||
findMatches(content) { | ||
let root = this, | ||
@@ -482,2 +544,3 @@ terms = root.searchTerms, | ||
} | ||
}); | ||
} | ||
customElements.define(SimpleSearch.is, SimpleSearch); |
@@ -1,2 +0,2 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@polymer/iron-icons/iron-icons.js"),require("@polymer/paper-input/paper-input.js"),require("@polymer/paper-tooltip/paper-tooltip.js"),require("@polymer/polymer/polymer-legacy.js"),require("@polymer/polymer/lib/legacy/polymer.dom.js")):"function"==typeof define&&define.amd?define(["@polymer/iron-icons/iron-icons.js","@polymer/paper-input/paper-input.js","@polymer/paper-tooltip/paper-tooltip.js","@polymer/polymer/polymer-legacy.js","@polymer/polymer/lib/legacy/polymer.dom.js"],n):n(null,null,null,e.polymerLegacy_js,e.polymer_dom_js)}(this,function(e,n,t,o,r){"use strict";var l=document.createElement("div");function a(){var e,n,t=(e=['\n <custom-style>\n <style is="custom-style">\n :host {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n width: 100%;\n }\n :host #input {\n flex-grow: 2;\n margin-right: 4px;\n --paper-input-container-input-color: var(--simple-search-input-text-color, #000);\n --paper-input-container-focus-color: var(--simple-search-input-line-color, #000);\n --paper-input-container-color: var(--simple-search-input-placeholder-color, #222);\n color: var(--simple-search-input-placeholder-color, #222);\n @apply --simple-search-container;\n }\n :host #xofy {\n margin: 8px;\n }\n :host button {\n margin: 8px 0 8px;\n color: var(--simple-search-button-color, #111);\n background-color: var(--simple-search-button-bg-color, #eee);\n border-color: var(--simple-search-button-border-color, #ccc);\n @apply --simple-search-button;\n }\n :host button:not([disabled]):focus,\n :host button:not([disabled]):hover {\n cursor: pointer;\n color: var(--simple-search-button-hover-color, #000);\n background-color: var(--simple-search-button-hover-bg-color, #fff);\n border-color: var(--simple-search-button-hover-border-color, #ddd);\n @apply --simple-search-button-hover;\n }\n :host button[disabled] {\n cursor: not-allowed;\n color: var(--simple-search-button-disabled-color, #999);\n background-color: var(--simple-search-button-disabled-bg-color, #eee);\n border-color: var(--simple-search-button-disabled-border-color, #ccc);\n @apply --simple-search-button-disabled;\n }\n :host button:not([controls]) {\n display: none;\n }\n :host [shrink-hide] {\n display: none;\n }\n </style>\n </custom-style>\n <paper-input id="input" always-float-label$="[[alwaysFloatLabel]]" label="[[searchInputLabel]]" no-label-float$="[[noLabelFloat]]">\n <iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon>\n </paper-input>\n <div id="xofy" shrink-hide$="[[noSearch]]"></div>\n <div shrink-hide$="[[noResults]]">\n <button id="prev" aria-label="[[prevButtonLabel]]" aria-role="button" controls$="[[controls]]" disabled$="[[prevButtonDisabled]]" tabindex="0">\n <iron-icon icon="[[prevButtonIcon]]"></iron-icon>\n </button>\n <paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip>\n <button id="next" aria-label="[[nextButtonLabel]]" aria-role="button" controls$="[[controls]]" disabled$="[[nextButtonDisabled]]" tabindex="0">\n <iron-icon icon$="[[nextButtonIcon]]"></iron-icon>\n </button>\n <paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip>\n </div>\n'],(n=['\n <custom-style>\n <style is="custom-style">\n :host {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n width: 100%;\n }\n :host #input {\n flex-grow: 2;\n margin-right: 4px;\n --paper-input-container-input-color: var(--simple-search-input-text-color, #000);\n --paper-input-container-focus-color: var(--simple-search-input-line-color, #000);\n --paper-input-container-color: var(--simple-search-input-placeholder-color, #222);\n color: var(--simple-search-input-placeholder-color, #222);\n @apply --simple-search-container;\n }\n :host #xofy {\n margin: 8px;\n }\n :host button {\n margin: 8px 0 8px;\n color: var(--simple-search-button-color, #111);\n background-color: var(--simple-search-button-bg-color, #eee);\n border-color: var(--simple-search-button-border-color, #ccc);\n @apply --simple-search-button;\n }\n :host button:not([disabled]):focus,\n :host button:not([disabled]):hover {\n cursor: pointer;\n color: var(--simple-search-button-hover-color, #000);\n background-color: var(--simple-search-button-hover-bg-color, #fff);\n border-color: var(--simple-search-button-hover-border-color, #ddd);\n @apply --simple-search-button-hover;\n }\n :host button[disabled] {\n cursor: not-allowed;\n color: var(--simple-search-button-disabled-color, #999);\n background-color: var(--simple-search-button-disabled-bg-color, #eee);\n border-color: var(--simple-search-button-disabled-border-color, #ccc);\n @apply --simple-search-button-disabled;\n }\n :host button:not([controls]) {\n display: none;\n }\n :host [shrink-hide] {\n display: none;\n }\n </style>\n </custom-style>\n <paper-input id="input" always-float-label\\$="[[alwaysFloatLabel]]" label="[[searchInputLabel]]" no-label-float\\$="[[noLabelFloat]]">\n <iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon>\n </paper-input>\n <div id="xofy" shrink-hide\\$="[[noSearch]]"></div>\n <div shrink-hide\\$="[[noResults]]">\n <button id="prev" aria-label="[[prevButtonLabel]]" aria-role="button" controls\\$="[[controls]]" disabled\\$="[[prevButtonDisabled]]" tabindex="0">\n <iron-icon icon="[[prevButtonIcon]]"></iron-icon>\n </button>\n <paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip>\n <button id="next" aria-label="[[nextButtonLabel]]" aria-role="button" controls\\$="[[controls]]" disabled\\$="[[nextButtonDisabled]]" tabindex="0">\n <iron-icon icon\\$="[[nextButtonIcon]]"></iron-icon>\n </button>\n <paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip>\n </div>\n'])||(n=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(n)}})));return a=function(){return t},t}l.setAttribute("style","display: none;"),l.innerHTML='<dom-module id="simple-search-content">\n<template>\n <style>\n :host #content {\n @apply --simple-search-content;\n }\n :host #content[match-number]{\n color: var(--simple-search-match-text-color, #000);\n background-color: var(--simple-search-match-bg-color, #f0f0f0);\n border: 1px solid; \n border-color: var(--simple-search-match-border-color, #ddd);\n padding: 0.16px 4px;\n border-radius: 0.16px;\n font-weight: bold;\n @apply --simple-search-match;\n }\n </style>\n <span id="content">\n <template is="dom-repeat" items="[[_searchedContent]]">\n <span match-number$="[[item.matchNumber]]" tabindex$="[[_getTabIndex(item.matchNumber)]]">[[item.text]]</span>\n </template>\n </span>\n </template>\n\n \n</dom-module>',document.head.appendChild(l),o.Polymer({is:"simple-search-content",properties:{content:{type:String,value:null}},enableSearch:function(e){var n=this,t=[{matched:!1,text:n.content}];null===t[0].text&&(t[0].text=r.dom(n).innerHTML),n.setContent(t),e.addEventListener("search",function(){n.setContent(t),n.setContent(e.findMatches(t))}),e.addEventListener("goto-result",function(e){n.focus(e.detail)})},setContent:function(e){this._searchedContent=e},focus:function(e){var n=this.$.content.querySelector('[match-number="'+e+'"]');null!=n&&n.focus()},_getTabIndex:function(e){return null!=e?"1":""}}),o.Polymer({_template:o.html(a()),is:"simple-search",properties:{alwaysFloatLabel:{type:Boolean,value:!1},caseSensitive:{type:Boolean,value:null},controls:{type:String,value:null},nextButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)"},nextButtonIcon:{type:String,value:"arrow-forward"},nextButtonLabel:{type:String,value:"next result"},noLabelFloat:{type:Boolean,value:!1},noResults:{type:Boolean,computed:"_hasNoResults(resultCount)"},noSearch:{type:Boolean,computed:"_hasNoSearch(searchTerms)"},prevButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)"},prevButtonIcon:{type:String,value:"arrow-back"},prevButtonLabel:{type:String,value:"previous result"},resultCount:{type:Number,value:0},resultPointer:{type:Number,value:0},resultsSpan:{type:String,computed:"_getResultsSpan(noSearch,resultPointer,resultCount)"},searchInputIcon:{type:String,value:"search"},searchInputLabel:{type:String,value:"search"},searchTerms:{type:Array,value:[]},target:{type:Object,value:null}},ready:function(){var e=this,n=e.$.input;e._getSearchText(n.value),e.addEventListener("change",function(t){e._getSearchText(n.value),e.resultCount=0,e.resultPointer=0,e.fire("search",e)}),e.$.prev.addEventListener("tap",function(n){e._navigateResults(-1)}),e.$.next.addEventListener("tap",function(n){e._navigateResults(1)})},_hasNoResults:function(e){return e<1},_hasNoSearch:function(e){return e.length<1},_getResultsSpan:function(e,n,t){var o="";return o=t>0&&n>0?n+"/"+t:" "+t,this.$.xofy.innerHTML=o,this.$.xofy.innerHTML},_navigateResults:function(e){this.resultPointer+e>0&&this.resultPointer+e<=this.resultCount&&(this.resultPointer+=e,this.fire("goto-result",this.resultPointer))},_isNavButtonDisabled:function(e,n,t,o){return""==t||e+o<=0||e+o>n},_getSearchText:function(e){var n=new Array;if(null!=e){n=e.split(/[\"\']/gm);for(var t=0;t<n.length;t++)n[t]=n[t].trim(),""===n[t]&&n.splice(t,1)}this.set("searchTerms",n.slice(0))},findMatches:function(e){for(var n=this,t=n.searchTerms,o=this.caseSensitive?"gm":"gim",r=e.slice(0),l=function(e){for(var t=0;t<r.length;t++)if(!1===r[t].matched){var l=new RegExp("\\b"+e+"\\b",o),a=r[t].text,i=a.search(l),s=i+e.length;if(i>-1){n.resultCount+=1;var c=a.slice(0,i),p=a.slice(i,s),u=a.slice(s,a.length);r.splice(t,1,{matched:!1,text:c,searchObject:n},{matched:!0,matchNumber:n.resultCount,text:p,searchObject:n},{matched:!1,text:u,searchObject:n})}}},a=0;a<t.length;a++)l(t[a]);return n.resultPointer=0,r}})}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@polymer/iron-icons/iron-icons.js"),require("@polymer/paper-input/paper-input.js"),require("@polymer/paper-tooltip/paper-tooltip.js"),require("@polymer/polymer/polymer-element.js")):"function"==typeof define&&define.amd?define(["exports","@polymer/iron-icons/iron-icons.js","@polymer/paper-input/paper-input.js","@polymer/paper-tooltip/paper-tooltip.js","@polymer/polymer/polymer-element.js"],t):t(e.SimpleSearch={},null,null,null,e.polymerElement_js)}(this,function(e,t,n,o,r){"use strict";function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function l(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}function i(e,t,n){return t&&l(e.prototype,t),n&&l(e,n),e}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}function c(e){return(c=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function u(e,t){return(u=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function p(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function h(e,t,n){return(h="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(e,t,n){var o=function(e,t){for(;!Object.prototype.hasOwnProperty.call(e,t)&&null!==(e=c(e)););return e}(e,t);if(o){var r=Object.getOwnPropertyDescriptor(o,t);return r.get?r.get.call(n):r.value}})(e,t,n||e)}function d(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function b(){var e=d(['<style>\n :host #content {\n @apply --simple-search-content;\n }\n :host #content[match-number]{\n color: var(--simple-search-match-text-color, #000);\n background-color: var(--simple-search-match-bg-color, #f0f0f0);\n border: 1px solid; \n border-color: var(--simple-search-match-border-color, #ddd);\n padding: 0.16px 4px;\n border-radius: 0.16px;\n font-weight: bold;\n @apply --simple-search-match;\n }\n </style>\n <span id="content">\n <template is="dom-repeat" items="[[_searchedContent]]">\n <span match-number$="[[item.matchNumber]]" tabindex$="[[_getTabIndex(item.matchNumber)]]">[[item.text]]</span>\n </template>\n </span>'],['<style>\n :host #content {\n @apply --simple-search-content;\n }\n :host #content[match-number]{\n color: var(--simple-search-match-text-color, #000);\n background-color: var(--simple-search-match-bg-color, #f0f0f0);\n border: 1px solid; \n border-color: var(--simple-search-match-border-color, #ddd);\n padding: 0.16px 4px;\n border-radius: 0.16px;\n font-weight: bold;\n @apply --simple-search-match;\n }\n </style>\n <span id="content">\n <template is="dom-repeat" items="[[_searchedContent]]">\n <span match-number\\$="[[item.matchNumber]]" tabindex\\$="[[_getTabIndex(item.matchNumber)]]">[[item.text]]</span>\n </template>\n </span>']);return b=function(){return e},e}var m=function(e){function t(){return a(this,t),p(this,c(t).apply(this,arguments))}return s(t,r.PolymerElement),i(t,[{key:"enableSearch",value:function(e){var t=this,n=[{matched:!1,text:this.content}];null===n[0].text&&(n[0].text=this.innerHTML),this.setContent(n),e.addEventListener("simple-search",function(){this.setContent(n),this.setContent(e.findMatches(n))}),e.addEventListener("goto-result",function(e){t.focus(e.detail)})}},{key:"setContent",value:function(e){this._searchedContent=e}},{key:"focus",value:function(e){var t=this.$.content.querySelector('[match-number="'+e+'"]');null!=t&&t.focus()}},{key:"_getTabIndex",value:function(e){return null!=e?"1":""}}],[{key:"is",get:function(){return"simple-search-content"}},{key:"properties",get:function(){return{content:{type:String,value:null}}}},{key:"template",get:function(){return r.html(b())}}]),t}();function f(){var e=d(['\n <style is="custom-style">\n :host {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n width: 100%;\n }\n :host #input {\n flex-grow: 2;\n margin-right: 4px;\n --paper-input-container-input-color: var(--simple-search-input-text-color, #000);\n --paper-input-container-focus-color: var(--simple-search-input-line-color, #000);\n --paper-input-container-color: var(--simple-search-input-placeholder-color, #222);\n color: var(--simple-search-input-placeholder-color, #222);\n @apply --simple-search-container;\n }\n :host #xofy {\n margin: 8px;\n }\n :host button {\n margin: 8px 0 8px;\n color: var(--simple-search-button-color, #111);\n background-color: var(--simple-search-button-bg-color, #eee);\n border-color: var(--simple-search-button-border-color, #ccc);\n @apply --simple-search-button;\n }\n :host button:not([disabled]):focus,\n :host button:not([disabled]):hover {\n cursor: pointer;\n color: var(--simple-search-button-hover-color, #000);\n background-color: var(--simple-search-button-hover-bg-color, #fff);\n border-color: var(--simple-search-button-hover-border-color, #ddd);\n @apply --simple-search-button-hover;\n }\n :host button[disabled] {\n cursor: not-allowed;\n color: var(--simple-search-button-disabled-color, #999);\n background-color: var(--simple-search-button-disabled-bg-color, #eee);\n border-color: var(--simple-search-button-disabled-border-color, #ccc);\n @apply --simple-search-button-disabled;\n }\n :host button:not([controls]) {\n display: none;\n }\n :host [shrink-hide] {\n display: none;\n }\n </style>\n <paper-input id="input" always-float-label$="[[alwaysFloatLabel]]" label="[[searchInputLabel]]" no-label-float$="[[noLabelFloat]]" on-change="_handleChange">\n <iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon>\n </paper-input>\n <div id="xofy" shrink-hide$="[[noSearch]]"></div>\n <div shrink-hide$="[[noResults]]">\n <button id="prev" aria-label="[[prevButtonLabel]]" aria-role="button" controls$="[[controls]]" disabled$="[[prevButtonDisabled]]" on-tap="_navigateResults" tabindex="0">\n <iron-icon icon="[[prevButtonIcon]]"></iron-icon>\n </button>\n <paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip>\n <button id="next" aria-label="[[nextButtonLabel]]" aria-role="button" controls$="[[controls]]" disabled$="[[nextButtonDisabled]]" on-tap="_navigateResults" tabindex="0">\n <iron-icon icon$="[[nextButtonIcon]]"></iron-icon>\n </button>\n <paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip>\n </div>'],['\n <style is="custom-style">\n :host {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n width: 100%;\n }\n :host #input {\n flex-grow: 2;\n margin-right: 4px;\n --paper-input-container-input-color: var(--simple-search-input-text-color, #000);\n --paper-input-container-focus-color: var(--simple-search-input-line-color, #000);\n --paper-input-container-color: var(--simple-search-input-placeholder-color, #222);\n color: var(--simple-search-input-placeholder-color, #222);\n @apply --simple-search-container;\n }\n :host #xofy {\n margin: 8px;\n }\n :host button {\n margin: 8px 0 8px;\n color: var(--simple-search-button-color, #111);\n background-color: var(--simple-search-button-bg-color, #eee);\n border-color: var(--simple-search-button-border-color, #ccc);\n @apply --simple-search-button;\n }\n :host button:not([disabled]):focus,\n :host button:not([disabled]):hover {\n cursor: pointer;\n color: var(--simple-search-button-hover-color, #000);\n background-color: var(--simple-search-button-hover-bg-color, #fff);\n border-color: var(--simple-search-button-hover-border-color, #ddd);\n @apply --simple-search-button-hover;\n }\n :host button[disabled] {\n cursor: not-allowed;\n color: var(--simple-search-button-disabled-color, #999);\n background-color: var(--simple-search-button-disabled-bg-color, #eee);\n border-color: var(--simple-search-button-disabled-border-color, #ccc);\n @apply --simple-search-button-disabled;\n }\n :host button:not([controls]) {\n display: none;\n }\n :host [shrink-hide] {\n display: none;\n }\n </style>\n <paper-input id="input" always-float-label\\$="[[alwaysFloatLabel]]" label="[[searchInputLabel]]" no-label-float\\$="[[noLabelFloat]]" on-change="_handleChange">\n <iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon>\n </paper-input>\n <div id="xofy" shrink-hide\\$="[[noSearch]]"></div>\n <div shrink-hide\\$="[[noResults]]">\n <button id="prev" aria-label="[[prevButtonLabel]]" aria-role="button" controls\\$="[[controls]]" disabled\\$="[[prevButtonDisabled]]" on-tap="_navigateResults" tabindex="0">\n <iron-icon icon="[[prevButtonIcon]]"></iron-icon>\n </button>\n <paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip>\n <button id="next" aria-label="[[nextButtonLabel]]" aria-role="button" controls\\$="[[controls]]" disabled\\$="[[nextButtonDisabled]]" on-tap="_navigateResults" tabindex="0">\n <iron-icon icon\\$="[[nextButtonIcon]]"></iron-icon>\n </button>\n <paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip>\n </div>']);return f=function(){return e},e}customElements.define(m.is,m);var v=function(e){function t(){return a(this,t),p(this,c(t).apply(this,arguments))}return s(t,r.PolymerElement),i(t,[{key:"ready",value:function(){h(c(t.prototype),"ready",this).call(this);var e=this.$.input;this._getSearchText(e.value)}},{key:"_handleChange",value:function(e){this._getSearchText(this.$.input.value),this.resultCount=0,this.resultPointer=0,this.dispatchEvent(new CustomEvent("simple-search",{detail:{search:this,content:e}}))}},{key:"_hasNoResults",value:function(e){return e<1}},{key:"_hasNoSearch",value:function(e){return e.length<1}},{key:"_getResultsSpan",value:function(e,t,n){var o="";return o=n>0&&t>0?t+"/"+n:" "+n,this.$.xofy.innerHTML=o,this.$.xofy.innerHTML}},{key:"_navigateResults",value:function(e){var t="next"===e.currentTarget.id?1:-1;this.resultPointer+t>0&&this.resultPointer+t<=this.resultCount&&(this.resultPointer+=t,this.dispatchEvent(new CustomEvent("goto-result",{detail:this.resultPointer})))}},{key:"_isNavButtonDisabled",value:function(e,t,n,o){return""==n||e+o<=0||e+o>t}},{key:"_getSearchText",value:function(e){var t=new Array;if(null!=e){t=e.split(/[\"\']/gm);for(var n=0;n<t.length;n++)t[n]=t[n].trim(),""===t[n]&&t.splice(n,1)}this.set("searchTerms",[]),this.set("searchTerms",t.slice(0))}},{key:"findMatches",value:function(e){for(var t=this,n=t.searchTerms,o=this.caseSensitive?"gm":"gim",r=e.slice(0),a=function(e){for(var n=0;n<r.length;n++)if(!1===r[n].matched){var a=new RegExp("\\b"+e+"\\b",o),l=r[n].text,i=l.search(a),s=i+e.length;if(i>-1){t.resultCount+=1;var c=l.slice(0,i),u=l.slice(i,s),p=l.slice(s,l.length);r.splice(n,1,{matched:!1,text:c,searchObject:t},{matched:!0,matchNumber:t.resultCount,text:u,searchObject:t},{matched:!1,text:p,searchObject:t})}}},l=0;l<n.length;l++)a(n[l]);return t.resultPointer=0,r}}],[{key:"is",get:function(){return"simple-search"}},{key:"properties",get:function(){return{alwaysFloatLabel:{type:Boolean,value:!1},caseSensitive:{type:Boolean,value:null},controls:{type:String,value:null},nextButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)"},nextButtonIcon:{type:String,value:"arrow-forward"},nextButtonLabel:{type:String,value:"next result"},noLabelFloat:{type:Boolean,value:!1},noResults:{type:Boolean,computed:"_hasNoResults(resultCount)"},noSearch:{type:Boolean,computed:"_hasNoSearch(searchTerms)"},prevButtonDisabled:{type:Boolean,computed:"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)"},prevButtonIcon:{type:String,value:"arrow-back"},prevButtonLabel:{type:String,value:"previous result"},resultCount:{type:Number,value:0},resultPointer:{type:Number,value:0},resultsSpan:{type:String,computed:"_getResultsSpan(noSearch,resultPointer,resultCount)"},searchInputIcon:{type:String,value:"search"},searchInputLabel:{type:String,value:"search"},searchTerms:{type:Array,value:[]},target:{type:Object,value:null}}}},{key:"template",get:function(){return r.html(f())}}]),t}();customElements.define(v.is,v),e.SimpleSearch=v,Object.defineProperty(e,"__esModule",{value:!0})}); | ||
//# sourceMappingURL=simple-search.umd.js.map |
@@ -1,2 +0,6 @@ | ||
import { html, Polymer } from "@polymer/polymer/polymer-legacy.js"; | ||
/** | ||
* Copyright 2018 The Pennsylvania State University | ||
* @license Apache-2.0, see License.md for full text. | ||
*/ | ||
import { html, PolymerElement } from "@polymer/polymer/polymer-element.js"; | ||
import "@polymer/iron-icons/iron-icons.js"; | ||
@@ -6,302 +10,335 @@ import "@polymer/paper-input/paper-input.js"; | ||
import "./lib/simple-search-content.js"; | ||
export { SimpleSearch }; | ||
/** | ||
`simple-search` | ||
A button used in simple-search | ||
* `simple-search` | ||
* `A button used in simple-search` | ||
* | ||
* | ||
* @microcopy - the mental model for this element | ||
* | ||
* ```<simple-search | ||
* case-sensitive$="[[caseSensitive]]" // is search case sensitive? | ||
* controls$="[[controls]]"> | ||
* </simple-search>``` | ||
* | ||
* The searchTerms property provides an array of search terms entered in to the input. | ||
* The findMatches function returns an array of parsed results. | ||
* For example if I searched for the with | ||
* `findMatches("The quick brown fox jumps over the lazy dog.")`, | ||
* the array would be: | ||
* ``[ | ||
* { | ||
* "matched": true, | ||
* "matchNumber": 1, | ||
* "text": "The" | ||
* },{ | ||
* "matched": false, | ||
* "text": " quick brown fox jumps over " | ||
* },{ | ||
* "matched": true, | ||
* "matchNumber": 2, | ||
* "text": "the" | ||
* },{ | ||
* "matched": false, | ||
* "text": " lazy dog." | ||
* } | ||
* ]``` | ||
* or `findMatches("The quick brown fox jumps over the lazy dog.",true)`, | ||
* the array would be: | ||
* ```[ | ||
* { | ||
* "matched": false, | ||
* "text": "The quick brown fox jumps over " | ||
* },{ | ||
* "matched": true, | ||
* "matchNumber": 1, | ||
* "text": "the" | ||
* },{ | ||
* "matched": false, | ||
* "text": " lazy dog." | ||
* } | ||
* ]``` | ||
* | ||
* CSS Variables: | ||
* For the input field... | ||
* ```--paper-input-container-input-color: var(--simple-search-input-color, #111); | ||
* --paper-input-container-focus-color: var(--simple-search-input-placeholder-color, #000); | ||
* --paper-input-container-color: var(--simple-search-input-line-color, #fff); | ||
* @apply --simple-search-container;``` | ||
* | ||
* For buttons: | ||
* ```color: var(--simple-search-button-color, #111); | ||
* background-color: var(--simple-search-button-bg-color, #eee); | ||
* border-color: var(--simple-search-button-border-color, #ccc); | ||
* @apply --simple-search-button;` | ||
* | ||
* For buttons on hover: | ||
* ```color: var(--simple-search-button-hover-color, #000); | ||
* background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
* border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
* @apply --simple-search-button-hover;``` | ||
* | ||
* For disabled buttons: | ||
* ```color: var(--simple-search-button-disabled-color, #666); | ||
* background-color: var(--simple-search-button-disabled-bg-color, #ccc); | ||
* border-color: var(--simple-search-button-disabled-border-color, #aaa); | ||
* @apply --simple-search-button-disabled;``` | ||
* | ||
* @polymer | ||
* @customElement | ||
* @demo demo/index.html | ||
* | ||
*/ | ||
class SimpleSearch extends PolymerElement { | ||
static get is() { | ||
return "simple-search"; | ||
} | ||
@demo demo/index.html | ||
static get properties() { | ||
return { | ||
/** | ||
* always float the label | ||
*/ | ||
alwaysFloatLabel: { | ||
type: Boolean, | ||
value: false | ||
}, | ||
/** | ||
* Is the search case-sensitive | ||
*/ | ||
caseSensitive: { | ||
type: Boolean, | ||
value: null | ||
}, | ||
/** | ||
* The id of the container element that the navigation buttons control | ||
*/ | ||
controls: { | ||
type: String, | ||
value: null | ||
}, | ||
/** | ||
* is the previous next button disabled | ||
*/ | ||
nextButtonDisabled: { | ||
type: Boolean, | ||
computed: | ||
"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)" | ||
}, | ||
/** | ||
* label for next result icon | ||
*/ | ||
nextButtonIcon: { | ||
type: String, | ||
value: "arrow-forward" | ||
}, | ||
/** | ||
* label for next result button | ||
*/ | ||
nextButtonLabel: { | ||
type: String, | ||
value: "next result" | ||
}, | ||
/** | ||
* never float the label | ||
*/ | ||
noLabelFloat: { | ||
type: Boolean, | ||
value: false | ||
}, | ||
/** | ||
* are there any results to navigate? | ||
*/ | ||
noResults: { | ||
type: Boolean, | ||
computed: "_hasNoResults(resultCount)" | ||
}, | ||
/** | ||
* is there an active search? | ||
*/ | ||
noSearch: { | ||
type: Boolean, | ||
computed: "_hasNoSearch(searchTerms)" | ||
}, | ||
/** | ||
* is the previous result button disabled | ||
*/ | ||
prevButtonDisabled: { | ||
type: Boolean, | ||
computed: | ||
"_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)" | ||
}, | ||
/** | ||
* label for previous result icon | ||
*/ | ||
prevButtonIcon: { | ||
type: String, | ||
value: "arrow-back" | ||
}, | ||
/** | ||
* label for previous result button | ||
*/ | ||
prevButtonLabel: { | ||
type: String, | ||
value: "previous result" | ||
}, | ||
/** | ||
* Number of results. | ||
*/ | ||
@microcopy - the mental model for this element | ||
<simple-search | ||
case-sensitive$="[[caseSensitive]]" // is search case sensitive? | ||
controls$="[[controls]]" | ||
> | ||
</simple-search> | ||
The searchTerms property provides an array of search terms entered in to the input. | ||
The findMatches function returns an array of parsed results. | ||
For example if I searched for the with | ||
findMatches("The quick brown fox jumps over the lazy dog."), | ||
the array would be: | ||
[ | ||
{ | ||
"matched": true, | ||
"matchNumber": 1, | ||
"text": "The" | ||
},{ | ||
"matched": false, | ||
"text": " quick brown fox jumps over " | ||
},{ | ||
"matched": true, | ||
"matchNumber": 2, | ||
"text": "the" | ||
},{ | ||
"matched": false, | ||
"text": " lazy dog." | ||
} | ||
] | ||
or findMatches("The quick brown fox jumps over the lazy dog.",true), | ||
the array would be: | ||
[ | ||
{ | ||
"matched": false, | ||
"text": "The quick brown fox jumps over " | ||
},{ | ||
"matched": true, | ||
"matchNumber": 1, | ||
"text": "the" | ||
},{ | ||
"matched": false, | ||
"text": " lazy dog." | ||
} | ||
] | ||
CSS Variables: | ||
For the input field... | ||
--paper-input-container-input-color: var(--simple-search-input-color, #111); | ||
--paper-input-container-focus-color: var(--simple-search-input-placeholder-color, #000); | ||
--paper-input-container-color: var(--simple-search-input-line-color, #fff); | ||
@apply --simple-search-container; | ||
For buttons: | ||
color: var(--simple-search-button-color, #111); | ||
background-color: var(--simple-search-button-bg-color, #eee); | ||
border-color: var(--simple-search-button-border-color, #ccc); | ||
@apply --simple-search-button; | ||
For buttons on hover: | ||
color: var(--simple-search-button-hover-color, #000); | ||
background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
@apply --simple-search-button-hover; | ||
For disabled buttons: | ||
color: var(--simple-search-button-disabled-color, #666); | ||
background-color: var(--simple-search-button-disabled-bg-color, #ccc); | ||
border-color: var(--simple-search-button-disabled-border-color, #aaa); | ||
@apply --simple-search-button-disabled; | ||
*/ | ||
Polymer({ | ||
_template: html` | ||
<custom-style> | ||
<style is="custom-style"> | ||
:host { | ||
display: flex; | ||
align-items: flex-end; | ||
justify-content: space-between; | ||
width: 100%; | ||
resultCount: { | ||
type: Number, | ||
value: 0 | ||
}, | ||
/** | ||
* Which result are we currently on? | ||
*/ | ||
resultPointer: { | ||
type: Number, | ||
value: 0 | ||
}, | ||
/** | ||
* Number of results. | ||
*/ | ||
resultsSpan: { | ||
type: String, | ||
computed: "_getResultsSpan(noSearch,resultPointer,resultCount)" | ||
}, | ||
/** | ||
* label for search icon | ||
*/ | ||
searchInputIcon: { | ||
type: String, | ||
value: "search" | ||
}, | ||
/** | ||
* label for search input | ||
*/ | ||
searchInputLabel: { | ||
type: String, | ||
value: "search" | ||
}, | ||
/** | ||
* an array of search terms | ||
*/ | ||
searchTerms: { | ||
type: Array, | ||
value: [] | ||
}, | ||
/** | ||
* The container element that the navigation buttons control | ||
*/ | ||
target: { | ||
type: Object, | ||
value: null | ||
} | ||
:host #input { | ||
flex-grow: 2; | ||
margin-right: 4px; | ||
--paper-input-container-input-color: var(--simple-search-input-text-color, #000); | ||
--paper-input-container-focus-color: var(--simple-search-input-line-color, #000); | ||
--paper-input-container-color: var(--simple-search-input-placeholder-color, #222); | ||
color: var(--simple-search-input-placeholder-color, #222); | ||
@apply --simple-search-container; | ||
} | ||
:host #xofy { | ||
margin: 8px; | ||
} | ||
:host button { | ||
margin: 8px 0 8px; | ||
color: var(--simple-search-button-color, #111); | ||
background-color: var(--simple-search-button-bg-color, #eee); | ||
border-color: var(--simple-search-button-border-color, #ccc); | ||
@apply --simple-search-button; | ||
} | ||
:host button:not([disabled]):focus, | ||
:host button:not([disabled]):hover { | ||
cursor: pointer; | ||
color: var(--simple-search-button-hover-color, #000); | ||
background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
@apply --simple-search-button-hover; | ||
} | ||
:host button[disabled] { | ||
cursor: not-allowed; | ||
color: var(--simple-search-button-disabled-color, #999); | ||
background-color: var(--simple-search-button-disabled-bg-color, #eee); | ||
border-color: var(--simple-search-button-disabled-border-color, #ccc); | ||
@apply --simple-search-button-disabled; | ||
} | ||
:host button:not([controls]) { | ||
display: none; | ||
} | ||
:host [shrink-hide] { | ||
display: none; | ||
} | ||
</style> | ||
</custom-style> | ||
<paper-input id="input" always-float-label\$="[[alwaysFloatLabel]]" label="[[searchInputLabel]]" no-label-float\$="[[noLabelFloat]]"> | ||
<iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon> | ||
</paper-input> | ||
<div id="xofy" shrink-hide\$="[[noSearch]]"></div> | ||
<div shrink-hide\$="[[noResults]]"> | ||
<button id="prev" aria-label="[[prevButtonLabel]]" aria-role="button" controls\$="[[controls]]" disabled\$="[[prevButtonDisabled]]" tabindex="0"> | ||
<iron-icon icon="[[prevButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip> | ||
<button id="next" aria-label="[[nextButtonLabel]]" aria-role="button" controls\$="[[controls]]" disabled\$="[[nextButtonDisabled]]" tabindex="0"> | ||
<iron-icon icon\$="[[nextButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip> | ||
</div> | ||
`, | ||
}; | ||
} | ||
is: "simple-search", | ||
// render function | ||
static get template() { | ||
return html` | ||
<style is="custom-style"> | ||
:host { | ||
display: flex; | ||
align-items: flex-end; | ||
justify-content: space-between; | ||
width: 100%; | ||
} | ||
:host #input { | ||
flex-grow: 2; | ||
margin-right: 4px; | ||
--paper-input-container-input-color: var( | ||
--simple-search-input-text-color, | ||
#000 | ||
); | ||
--paper-input-container-focus-color: var( | ||
--simple-search-input-line-color, | ||
#000 | ||
); | ||
--paper-input-container-color: var( | ||
--simple-search-input-placeholder-color, | ||
#222 | ||
); | ||
color: var(--simple-search-input-placeholder-color, #222); | ||
@apply --simple-search-container; | ||
} | ||
:host #xofy { | ||
margin: 8px; | ||
} | ||
:host button { | ||
margin: 8px 0 8px; | ||
color: var(--simple-search-button-color, #111); | ||
background-color: var(--simple-search-button-bg-color, #eee); | ||
border-color: var(--simple-search-button-border-color, #ccc); | ||
@apply --simple-search-button; | ||
} | ||
:host button:not([disabled]):focus, | ||
:host button:not([disabled]):hover { | ||
cursor: pointer; | ||
color: var(--simple-search-button-hover-color, #000); | ||
background-color: var(--simple-search-button-hover-bg-color, #fff); | ||
border-color: var(--simple-search-button-hover-border-color, #ddd); | ||
@apply --simple-search-button-hover; | ||
} | ||
:host button[disabled] { | ||
cursor: not-allowed; | ||
color: var(--simple-search-button-disabled-color, #999); | ||
background-color: var(--simple-search-button-disabled-bg-color, #eee); | ||
border-color: var(--simple-search-button-disabled-border-color, #ccc); | ||
@apply --simple-search-button-disabled; | ||
} | ||
:host button:not([controls]) { | ||
display: none; | ||
} | ||
:host [shrink-hide] { | ||
display: none; | ||
} | ||
</style> | ||
<paper-input | ||
id="input" | ||
always-float-label\$="[[alwaysFloatLabel]]" | ||
label="[[searchInputLabel]]" | ||
no-label-float\$="[[noLabelFloat]]" | ||
on-change="_handleChange" | ||
> | ||
<iron-icon icon="[[searchInputIcon]]" slot="prefix"></iron-icon> | ||
</paper-input> | ||
<div id="xofy" shrink-hide\$="[[noSearch]]"></div> | ||
<div shrink-hide\$="[[noResults]]"> | ||
<button | ||
id="prev" | ||
aria-label="[[prevButtonLabel]]" | ||
aria-role="button" | ||
controls\$="[[controls]]" | ||
disabled\$="[[prevButtonDisabled]]" | ||
on-tap="_navigateResults" | ||
tabindex="0" | ||
> | ||
<iron-icon icon="[[prevButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="prev">[[prevButtonLabel]]</paper-tooltip> | ||
<button | ||
id="next" | ||
aria-label="[[nextButtonLabel]]" | ||
aria-role="button" | ||
controls\$="[[controls]]" | ||
disabled\$="[[nextButtonDisabled]]" | ||
on-tap="_navigateResults" | ||
tabindex="0" | ||
> | ||
<iron-icon icon\$="[[nextButtonIcon]]"></iron-icon> | ||
</button> | ||
<paper-tooltip for="next">[[nextButtonLabel]]</paper-tooltip> | ||
</div> | ||
`; | ||
} | ||
properties: { | ||
/** | ||
* always float the label | ||
*/ | ||
alwaysFloatLabel: { | ||
type: Boolean, | ||
value: false | ||
}, | ||
/** | ||
* Is the search case-sensitive | ||
*/ | ||
caseSensitive: { | ||
type: Boolean, | ||
value: null | ||
}, | ||
/** | ||
* The id of the container element that the navigation buttons control | ||
*/ | ||
controls: { | ||
type: String, | ||
value: null | ||
}, | ||
/** | ||
* is the previous next button disabled | ||
*/ | ||
nextButtonDisabled: { | ||
type: Boolean, | ||
computed: "_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,1)" | ||
}, | ||
/** | ||
* label for next result icon | ||
*/ | ||
nextButtonIcon: { | ||
type: String, | ||
value: "arrow-forward" | ||
}, | ||
/** | ||
* label for next result button | ||
*/ | ||
nextButtonLabel: { | ||
type: String, | ||
value: "next result" | ||
}, | ||
/** | ||
* never float the label | ||
*/ | ||
noLabelFloat: { | ||
type: Boolean, | ||
value: false | ||
}, | ||
/** | ||
* are there any results to navigate? | ||
*/ | ||
noResults: { | ||
type: Boolean, | ||
computed: "_hasNoResults(resultCount)" | ||
}, | ||
/** | ||
* is there an active search? | ||
*/ | ||
noSearch: { | ||
type: Boolean, | ||
computed: "_hasNoSearch(searchTerms)" | ||
}, | ||
/** | ||
* is the previous result button disabled | ||
*/ | ||
prevButtonDisabled: { | ||
type: Boolean, | ||
computed: "_isNavButtonDisabled(resultPointer,resultCount,resultsSpan,-1)" | ||
}, | ||
/** | ||
* label for previous result icon | ||
*/ | ||
prevButtonIcon: { | ||
type: String, | ||
value: "arrow-back" | ||
}, | ||
/** | ||
* label for previous result button | ||
*/ | ||
prevButtonLabel: { | ||
type: String, | ||
value: "previous result" | ||
}, | ||
/** | ||
* Number of results. | ||
*/ | ||
resultCount: { | ||
type: Number, | ||
value: 0 | ||
}, | ||
/** | ||
* Which result are we currently on? | ||
*/ | ||
resultPointer: { | ||
type: Number, | ||
value: 0 | ||
}, | ||
/** | ||
* Number of results. | ||
*/ | ||
resultsSpan: { | ||
type: String, | ||
computed: "_getResultsSpan(noSearch,resultPointer,resultCount)" | ||
}, | ||
/** | ||
* label for search icon | ||
*/ | ||
searchInputIcon: { | ||
type: String, | ||
value: "search" | ||
}, | ||
/** | ||
* label for search input | ||
*/ | ||
searchInputLabel: { | ||
type: String, | ||
value: "search" | ||
}, | ||
/** | ||
* an array of search terms | ||
*/ | ||
searchTerms: { | ||
type: Array, | ||
value: [] | ||
}, | ||
/** | ||
* The container element that the navigation buttons control | ||
*/ | ||
target: { | ||
type: Object, | ||
value: null | ||
} | ||
}, | ||
ready: function() { | ||
ready() { | ||
super.ready(); | ||
let root = this, | ||
search = root.$.input; | ||
root._getSearchText(search.value); | ||
root.addEventListener("change", function(e) { | ||
root._getSearchText(search.value); | ||
root.resultCount = 0; | ||
root.resultPointer = 0; | ||
root.fire("search", root); | ||
}); | ||
root.$.prev.addEventListener("tap", function(e) { | ||
root._navigateResults(-1); | ||
}); | ||
root.$.next.addEventListener("tap", function(e) { | ||
root._navigateResults(1); | ||
}); | ||
}, | ||
} | ||
@@ -311,17 +348,41 @@ /** | ||
*/ | ||
_hasNoResults: function(resultCount) { | ||
_handleChange(e) { | ||
let root = this; | ||
root._getSearchText(root.$.input.value); | ||
root.resultCount = 0; | ||
root.resultPointer = 0; | ||
root.dispatchEvent( | ||
new CustomEvent("simple-search", { detail: { search: root, content: e } }) | ||
); | ||
} | ||
/** | ||
* are there any results to navigate? | ||
* | ||
* @param {number} total number of results | ||
* @returns {boolean} whether or not there are results | ||
*/ | ||
_hasNoResults(resultCount) { | ||
return resultCount < 1; | ||
}, | ||
} | ||
/** | ||
* are there any results to navigate? | ||
* | ||
* @param {array} array of search terms | ||
* @returns {boolean} whether or not there are search terms | ||
*/ | ||
_hasNoSearch: function(searchTerms) { | ||
_hasNoSearch(searchTerms) { | ||
return searchTerms.length < 1; | ||
}, | ||
} | ||
/** | ||
* get results span text | ||
* | ||
* @param {boolean} whether or not there are search terms | ||
* @param {number} the current search result's position | ||
* @param {number} the total number of search results | ||
* @returns {string} "y results" or "x/y" text | ||
*/ | ||
_getResultsSpan: function(noSearch, resultPointer, resultCount) { | ||
_getResultsSpan(noSearch, resultPointer, resultCount) { | ||
let html = ""; | ||
@@ -335,3 +396,3 @@ if (resultCount > 0 && resultPointer > 0) { | ||
return this.$.xofy.innerHTML; | ||
}, | ||
} | ||
@@ -341,3 +402,5 @@ /** | ||
*/ | ||
_navigateResults: function(increment) { | ||
_navigateResults(e) { | ||
let root = this, | ||
increment = e.currentTarget.id === "next" ? 1 : -1; | ||
if ( | ||
@@ -348,5 +411,7 @@ this.resultPointer + increment > 0 && | ||
this.resultPointer += increment; | ||
this.fire("goto-result", this.resultPointer); | ||
this.dispatchEvent( | ||
new CustomEvent("goto-result", { detail: this.resultPointer }) | ||
); | ||
} | ||
}, | ||
} | ||
@@ -356,19 +421,12 @@ /** | ||
*/ | ||
_isNavButtonDisabled: function( | ||
resultPointer, | ||
resultCount, | ||
resultsSpan, | ||
increment | ||
) { | ||
return ( | ||
resultsSpan == "" || | ||
resultPointer + increment <= 0 || | ||
resultPointer + increment > resultCount | ||
); | ||
}, | ||
_isNavButtonDisabled(pointer, count, span, inc) { | ||
return span == "" || pointer + inc <= 0 || pointer + inc > count; | ||
} | ||
/** | ||
* gets the tab-index of cues based on whether or not interactive cues are disabled | ||
* | ||
* @param {string} a string of search text | ||
*/ | ||
_getSearchText: function(find) { | ||
_getSearchText(find) { | ||
let temp = new Array(); | ||
@@ -382,4 +440,5 @@ if (find !== undefined && find !== null) { | ||
} | ||
this.set("searchTerms", []); | ||
this.set("searchTerms", temp.slice(0)); | ||
}, | ||
} | ||
@@ -389,5 +448,5 @@ /** | ||
* For example if I searched for the with | ||
* findMatches("The quick brown fox jumps over the lazy dog."), | ||
* `findMatches("The quick brown fox jumps over the lazy dog.")`, | ||
* the array would be: | ||
* [ | ||
* ```[ | ||
* { | ||
@@ -412,7 +471,7 @@ * "matched": true, | ||
* } | ||
* ] | ||
* ]``` | ||
* | ||
* or findMatches("The quick brown fox jumps over the lazy dog.",true), | ||
* or `findMatches("The quick brown fox jumps over the lazy dog.",true)`, | ||
* the array would be: | ||
* [ | ||
* ```[ | ||
* { | ||
@@ -432,5 +491,8 @@ * "matched": false, | ||
* } | ||
* ] | ||
* ]``` | ||
* | ||
* @param {array} an array of search terms | ||
* @returns {array} an array of search results | ||
*/ | ||
findMatches: function(content) { | ||
findMatches(content) { | ||
let root = this, | ||
@@ -482,2 +544,3 @@ terms = root.searchTerms, | ||
} | ||
}); | ||
} | ||
customElements.define(SimpleSearch.is, SimpleSearch); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
407010
10261
22
3