diff --git a/package-lock.json b/package-lock.json
index 8f1ff8e4..ae816955 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2459,9 +2459,9 @@
}
},
"core-js": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.5.0.tgz",
- "integrity": "sha512-Ifh3kj78gzQ7NAoJXeTu+XwzDld0QRIwjBLRqAMhuLhP3d2Av5wmgE9ycfnvK6NAEjTkQ1sDPeoEZAWO3Hx1Uw==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.0.tgz",
+ "integrity": "sha512-AHPTNKzyB+YwgDWoSOCaid9PUSEF6781vsfiK8qUz62zRR448/XgK2NtCbpiUGizbep8Lrpt0Du19PpGGZvw3Q==",
"dev": true
}
}
@@ -2778,6 +2778,11 @@
"@types/istanbul-lib-report": "*"
}
},
+ "@types/node": {
+ "version": "12.12.21",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.21.tgz",
+ "integrity": "sha512-8sRGhbpU+ck1n0PGAUgVrWrWdjSW2aqNeyC15W88GRsMpSwzv6RJGlLhE7s2RhVSOdyDmxbqlWSeThq4/7xqlA=="
+ },
"@types/normalize-package-data": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
@@ -3662,6 +3667,11 @@
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
"dev": true
},
+ "array-filter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
+ "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM="
+ },
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@@ -5158,6 +5168,38 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
+ "cheerio": {
+ "version": "1.0.0-rc.3",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
+ "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
+ "requires": {
+ "css-select": "~1.2.0",
+ "dom-serializer": "~0.1.1",
+ "entities": "~1.1.1",
+ "htmlparser2": "^3.9.1",
+ "lodash": "^4.15.0",
+ "parse5": "^3.0.1"
+ },
+ "dependencies": {
+ "dom-serializer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
+ "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
+ "requires": {
+ "domelementtype": "^1.3.0",
+ "entities": "^1.1.1"
+ }
+ },
+ "parse5": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
+ "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ }
+ }
+ },
"chokidar": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
@@ -5416,8 +5458,7 @@
"commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
- "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
- "dev": true
+ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
},
"common-tags": {
"version": "1.8.0",
@@ -5936,7 +5977,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
- "dev": true,
"requires": {
"boolbase": "~1.0.0",
"css-what": "2.1",
@@ -5948,7 +5988,6 @@
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
- "dev": true,
"requires": {
"dom-serializer": "0",
"domelementtype": "1"
@@ -6025,8 +6064,7 @@
"css-what": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
- "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
- "dev": true
+ "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
},
"cssesc": {
"version": "3.0.0",
@@ -6132,7 +6170,8 @@
"de-indent": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
- "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0="
+ "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
+ "dev": true
},
"debug": {
"version": "4.1.1",
@@ -6340,6 +6379,11 @@
"path-type": "^3.0.0"
}
},
+ "discontinuous-range": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
+ "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo="
+ },
"dom-converter": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
@@ -6415,7 +6459,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
- "dev": true,
"requires": {
"domelementtype": "1"
}
@@ -6640,8 +6683,171 @@
"entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
- "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
- "dev": true
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
+ },
+ "enzyme": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz",
+ "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==",
+ "requires": {
+ "array.prototype.flat": "^1.2.3",
+ "cheerio": "^1.0.0-rc.3",
+ "enzyme-shallow-equal": "^1.0.1",
+ "function.prototype.name": "^1.1.2",
+ "has": "^1.0.3",
+ "html-element-map": "^1.2.0",
+ "is-boolean-object": "^1.0.1",
+ "is-callable": "^1.1.5",
+ "is-number-object": "^1.0.4",
+ "is-regex": "^1.0.5",
+ "is-string": "^1.0.5",
+ "is-subset": "^0.1.1",
+ "lodash.escape": "^4.0.1",
+ "lodash.isequal": "^4.5.0",
+ "object-inspect": "^1.7.0",
+ "object-is": "^1.0.2",
+ "object.assign": "^4.1.0",
+ "object.entries": "^1.1.1",
+ "object.values": "^1.1.1",
+ "raf": "^3.4.1",
+ "rst-selector-parser": "^2.2.3",
+ "string.prototype.trim": "^1.2.1"
+ },
+ "dependencies": {
+ "array.prototype.flat": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz",
+ "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz",
+ "integrity": "sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==",
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.1.5",
+ "is-regex": "^1.0.5",
+ "object-inspect": "^1.7.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.0",
+ "string.prototype.trimleft": "^2.1.1",
+ "string.prototype.trimright": "^2.1.1"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "function.prototype.name": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.2.tgz",
+ "integrity": "sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1",
+ "functions-have-names": "^1.2.0"
+ }
+ },
+ "functions-have-names": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.0.tgz",
+ "integrity": "sha512-zKXyzksTeaCSw5wIX79iCA40YAa6CJMJgNg9wdkU/ERBrIdPSimPICYiLp65lRbSBqtiHql/HZfS2DyI/AH6tQ=="
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
+ },
+ "is-callable": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+ "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q=="
+ },
+ "is-regex": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+ "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "object-inspect": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+ "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
+ },
+ "object.entries": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz",
+ "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3"
+ }
+ },
+ "object.values": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
+ "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3"
+ }
+ },
+ "string.prototype.trimleft": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
+ "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ }
+ },
+ "string.prototype.trimright": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
+ "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ }
+ }
+ }
+ },
+ "enzyme-shallow-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.1.tgz",
+ "integrity": "sha512-hGA3i1so8OrYOZSM9whlkNmVHOicJpsjgTzC+wn2JMJXhq1oO4kA4bJ5MsfzSIcC71aLDKzJ6gZpIxrqt3QTAQ==",
+ "requires": {
+ "has": "^1.0.3",
+ "object-is": "^1.0.2"
+ }
+ },
+ "enzyme-to-json": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.4.3.tgz",
+ "integrity": "sha512-jqNEZlHqLdz7OTpXSzzghArSS3vigj67IU/fWkPyl1c0TCj9P5s6Ze0kRkYZWNEoCqCR79xlQbigYlMx5erh8A==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.15"
+ }
},
"errno": {
"version": "0.1.7",
@@ -8622,7 +8828,8 @@
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
- "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true
},
"highlight.js": {
"version": "9.12.0",
@@ -8656,6 +8863,14 @@
"integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==",
"dev": true
},
+ "html-element-map": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.2.0.tgz",
+ "integrity": "sha512-0uXq8HsuG1v2TmQ8QkIhzbrqeskE4kn52Q18QJ9iAA/SnHoEKXWiUxHQtclRsCFWEUD2So34X+0+pZZu862nnw==",
+ "requires": {
+ "array-filter": "^1.0.0"
+ }
+ },
"html-encoding-sniffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
@@ -8736,7 +8951,6 @@
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
- "dev": true,
"requires": {
"domelementtype": "^1.3.1",
"domhandler": "^2.3.0",
@@ -8750,7 +8964,6 @@
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
- "dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -9077,6 +9290,11 @@
"binary-extensions": "^1.0.0"
}
},
+ "is-boolean-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.1.tgz",
+ "integrity": "sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ=="
+ },
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -9255,6 +9473,11 @@
}
}
},
+ "is-number-object": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz",
+ "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw=="
+ },
"is-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
@@ -9314,6 +9537,16 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
+ "is-string": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+ "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ=="
+ },
+ "is-subset": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
+ "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY="
+ },
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
@@ -10428,8 +10661,7 @@
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
- "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
- "dev": true
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"lodash.camelcase": {
"version": "4.3.0",
@@ -10443,6 +10675,21 @@
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
"dev": true
},
+ "lodash.escape": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz",
+ "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg="
+ },
+ "lodash.flattendeep": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI="
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+ },
"lodash.kebabcase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
@@ -10936,6 +11183,11 @@
}
}
},
+ "moo": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/moo/-/moo-0.4.3.tgz",
+ "integrity": "sha512-gFD2xGCl8YFgGHsqJ9NKRVdwlioeW3mI1iqfLNYQOv0+6JRwG58Zk9DIGQgyIaffSYaO1xsKnMaYzzNr1KyIAw=="
+ },
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -10994,6 +11246,18 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
+ "nearley": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.0.tgz",
+ "integrity": "sha512-2v52FTw7RPqieZr3Gth1luAXZR7Je6q3KaDHY5bjl/paDUdMu35fZ8ICNgiYJRr3tf3NMvIQQR1r27AvEr9CRA==",
+ "requires": {
+ "commander": "^2.19.0",
+ "moo": "^0.4.3",
+ "railroad-diagrams": "^1.0.0",
+ "randexp": "0.4.6",
+ "semver": "^5.4.1"
+ }
+ },
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
@@ -11295,6 +11559,11 @@
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
"integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ=="
},
+ "object-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz",
+ "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ=="
+ },
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
@@ -11318,7 +11587,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
- "dev": true,
"requires": {
"define-properties": "^1.1.2",
"function-bind": "^1.1.1",
@@ -11766,8 +12034,7 @@
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
- "dev": true
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"pify": {
"version": "4.0.1",
@@ -12275,12 +12542,34 @@
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
"dev": true
},
+ "raf": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
+ "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
+ "requires": {
+ "performance-now": "^2.1.0"
+ }
+ },
+ "railroad-diagrams": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
+ "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234="
+ },
"ramda": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz",
"integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=",
"dev": true
},
+ "randexp": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
+ "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
+ "requires": {
+ "discontinuous-range": "1.0.0",
+ "ret": "~0.1.10"
+ }
+ },
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -13233,8 +13522,7 @@
"ret": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
- "dev": true
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
},
"rework": {
"version": "1.0.1",
@@ -13276,6 +13564,15 @@
"inherits": "^2.0.1"
}
},
+ "rst-selector-parser": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz",
+ "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=",
+ "requires": {
+ "lodash.flattendeep": "^4.4.0",
+ "nearley": "^2.7.10"
+ }
+ },
"rsvp": {
"version": "4.8.5",
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
@@ -13431,8 +13728,7 @@
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "dev": true
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"semver-diff": {
"version": "2.1.0",
@@ -14205,6 +14501,87 @@
"function-bind": "^1.0.2"
}
},
+ "string.prototype.trim": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz",
+ "integrity": "sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1",
+ "function-bind": "^1.1.1"
+ },
+ "dependencies": {
+ "es-abstract": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz",
+ "integrity": "sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==",
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.1.5",
+ "is-regex": "^1.0.5",
+ "object-inspect": "^1.7.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.0",
+ "string.prototype.trimleft": "^2.1.1",
+ "string.prototype.trimright": "^2.1.1"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
+ },
+ "is-callable": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+ "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q=="
+ },
+ "is-regex": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+ "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "object-inspect": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+ "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
+ },
+ "string.prototype.trimleft": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
+ "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ }
+ },
+ "string.prototype.trimright": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
+ "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ }
+ }
+ }
+ },
"string.prototype.trimleft": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz",
@@ -14227,7 +14604,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -15227,8 +15603,7 @@
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
- "dev": true
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"util.promisify": {
"version": "1.0.0",
@@ -15291,9 +15666,9 @@
"dev": true
},
"vue": {
- "version": "2.6.10",
- "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
- "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==",
+ "version": "2.6.11",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
+ "integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==",
"dev": true
},
"vue-class-component": {
@@ -15380,9 +15755,10 @@
}
},
"vue-template-compiler": {
- "version": "2.6.10",
- "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz",
- "integrity": "sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==",
+ "version": "2.6.11",
+ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz",
+ "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==",
+ "dev": true,
"requires": {
"de-indent": "^1.0.2",
"he": "^1.1.0"
diff --git a/package.json b/package.json
index 189c6530..8edf8861 100644
--- a/package.json
+++ b/package.json
@@ -15,15 +15,15 @@
"test-chunk": "vue-cli-service build src/testChunk/main.js && cd ./dist && http-server"
},
"dependencies": {
- "material-design-icons-iconfont": "^5.0.1",
"@fortawesome/fontawesome-free": "^5.11.2",
"@mdi/font": "^4.5.95",
"@mdi/js": "^4.5.95",
- "vue-the-mask": "^0.11.1",
- "vue-svg-loader": "^0.15.0",
- "vue-template-compiler": "^2.6.10",
"copy-to-clipboard": "^3.2.0",
- "resolve-url-loader": "^3.1.0"
+ "enzyme": "^3.11.0",
+ "material-design-icons-iconfont": "^5.0.1",
+ "resolve-url-loader": "^3.1.0",
+ "vue-svg-loader": "^0.15.0",
+ "vue-the-mask": "^0.11.1"
},
"devDependencies": {
"@babel/core": "^7.6.2",
@@ -55,6 +55,7 @@
"core-js": "2.6.9",
"css-loader": "^3.2.0",
"dayjs": "^1.8.16",
+ "enzyme-to-json": "^3.4.3",
"expect": "latest",
"github-markdown-css": "^3.0.1",
"jest": "^24.9.0",
@@ -75,12 +76,12 @@
"sass-loader": "^8.0.0",
"storybook-addon-specifications": "^2.1.5",
"traverse": "^0.6.6",
- "vue": "^2.6.10",
+ "vue": "^2.6.11",
"vue-fragment": "^1.5.1",
"vue-jest": "^3.0.5",
"vue-loader": "^15.7.1",
"vue-router": "^3.1.3",
- "vue-template-compiler": "^2.6.10"
+ "vue-template-compiler": "^2.6.11"
},
"postcss": {
"plugins": {
diff --git a/src/components/GAutocomplete/GAutocomplete.vue b/src/components/GAutocomplete/GAutocomplete.vue
index 8c91fc5b..8765e008 100644
--- a/src/components/GAutocomplete/GAutocomplete.vue
+++ b/src/components/GAutocomplete/GAutocomplete.vue
@@ -1,348 +1,42 @@
-
diff --git a/src/components/GAutocomplete/GAutocompleteFactory.js b/src/components/GAutocomplete/GAutocompleteFactory.js
index 013b6113..8204c6c6 100644
--- a/src/components/GAutocomplete/GAutocompleteFactory.js
+++ b/src/components/GAutocomplete/GAutocompleteFactory.js
@@ -1,32 +1,32 @@
import { keyCodes } from '../../utils/helpers';
-export function getInputEventHandlers(props, context, state, selections, selectedItem, isFocused, toggleItem) {
+export function getInputEventHandlers(props, context, state, selections, selectedItem, isFocused, toggleItem, showOptions) {
const isInputDisplay = !props.multiple && !(props.chips || props.smallChips || props.deletableChips)
+
function onChipCloseClick(index = null) {
- if (props.multiple) {
- selectedItem.value.splice(index, 1);
- } else {
- selectedItem.value = null
- }
+ let _value = props.multiple ? selectedItem.value.splice(index, 1) : null
+ context.emit('input', _value)
}
function clearSelection() {
- selectedItem.value = props.multiple ? [] : ''
- setSearch(props, context, selections, state)
+ // selectedItem.value = props.multiple ? [] : ''
+ if(props.component !== 'select') setSearch(props, context, selections, state)
+ context.emit('input', props.multiple ? [] : '')
}
function onInputKeyDown(e) {
- resetSelectionsDisplay(state)
+ if(props.component !== 'select')resetSelectionsDisplay(state)
if (e.keyCode === keyCodes.down) {
- const listRef = context.refs.list
+ const listRef = context.refs.menu.$refs.list
listRef.$el.getElementsByClassName('g-list-item')[0].focus()
}
}
function onInputChange(text) {
+ if(props.component === 'select') return
state.searchText = text
- if (selectedItem.value && isInputDisplay) {
- selectedItem.value = ''
+ if (selectedItem.value && isInputDisplay && props.component === 'combobox') {
+ context.emit('input', '')
}
context.emit('update:searchText', text)
}
@@ -43,9 +43,7 @@ export function getInputEventHandlers(props, context, state, selections, selecte
}
function onInputDelete() {
- if (isInputDisplay) {
- return
- }
+ if (isInputDisplay) return
if (state.searchText) {
return state.pressDeleteTimes = 0
} else {
@@ -64,6 +62,7 @@ export function getInputEventHandlers(props, context, state, selections, selecte
}
const inputAddSelection = () => {
+ if (props.component !== 'combobox') return
if (state.searchText.trim().length > 0) {
toggleItem(parseInt(state.searchText) || state.searchText)
setSearch(props, context, selections, state)
@@ -90,3 +89,6 @@ export function setSearch(props, context, selections, state) {
state.searchText = ''
})
}
+
+
+
diff --git a/src/components/GAutocomplete/__story__/GAutocomplete.stories.js b/src/components/GAutocomplete/__story__/GAutocomplete.stories.js
index 06a7e212..c81bee3f 100644
--- a/src/components/GAutocomplete/__story__/GAutocomplete.stories.js
+++ b/src/components/GAutocomplete/__story__/GAutocomplete.stories.js
@@ -1,5 +1,8 @@
-import {boolean, object, text, withKnobs} from '@storybook/addon-knobs';
-import {action} from '@storybook/addon-actions'
+import { boolean, object, text, withKnobs } from '@storybook/addon-knobs';
+// testing
+import Vue from 'vue/dist/vue.common.js'
+import GAutocomplete from '../GAutocomplete';
+import GSelect from '../../GSelect/GSelect';
//
export default {
@@ -43,7 +46,7 @@ export const GAutocompleteSingleSelect = () => ({
{text: 'Cindy Baker', value: 'https://cdn.vuetifyjs.com/images/lists/3.jpg'},
{text: 'Ali Connors', value: 'https://cdn.vuetifyjs.com/images/lists/4.jpg'},
],
- selected: null,
+ selected: 'abc',
filters: [
{
value: 0,
@@ -203,8 +206,8 @@ export const GAutocompleteSingleSelectPrimitive = () => ({
hint: {default: text('hint', 'Hint')},
persistent: {default: boolean('persistent', false)},
counter: {type: [String, Number], default: Number('counter', 25)},
- itemText: {default: text('itemText', '')},
- itemValue: {default: text('itemValue', '')},
+ itemText: {default: text('itemText', 'text')},
+ itemValue: {default: text('itemValue', 'value')},
chips: {default: boolean('chips', false)},
smallChips: {default: boolean('smallChips', false)},
deletableChips: {default: boolean('deletable-chips', false)},
@@ -224,7 +227,7 @@ export const GAutocompleteSingleSelectPrimitive = () => ({
'Ali Connors',
'Ranee Carlson',
],
- selected: 'Cindy Baker',
+ selected: 'abc',
filters: [
{
value: 0,
@@ -465,10 +468,6 @@ export const GAutocompleteMultiSelectAllowDuplicate = () => ({
{{'filter: '+activeFilter}}
`,
})
-// testing
-import Vue from 'vue/dist/vue.common.js'
-import GAutocomplete from "../GAutocomplete";
-import GSelect from "../../GSelect/GSelect";
describe('test', function () {
it('should', function () {
diff --git a/src/components/GCombobox/GCombobox.vue b/src/components/GCombobox/GCombobox.vue
index 3dda51d9..4cd2751e 100644
--- a/src/components/GCombobox/GCombobox.vue
+++ b/src/components/GCombobox/GCombobox.vue
@@ -1,383 +1,42 @@
-
diff --git a/src/components/GCombobox/SelectableComponent.vue b/src/components/GCombobox/SelectableComponent.vue
new file mode 100644
index 00000000..bd0b2a24
--- /dev/null
+++ b/src/components/GCombobox/SelectableComponent.vue
@@ -0,0 +1,339 @@
+
+
diff --git a/src/components/GCombobox/__story__/GCombobox.stories.js b/src/components/GCombobox/__story__/GCombobox.stories.js
index ec5c8a19..04117a9d 100644
--- a/src/components/GCombobox/__story__/GCombobox.stories.js
+++ b/src/components/GCombobox/__story__/GCombobox.stories.js
@@ -1,5 +1,9 @@
-import {boolean, number, object, text, withKnobs} from '@storybook/addon-knobs';
-import {action} from '@storybook/addon-actions'
+import { boolean, number, object, text, withKnobs } from '@storybook/addon-knobs';
+// testing
+import Vue from 'vue/dist/vue.common.js'
+import GCombobox from '../GCombobox';
+import GListItem from '../../GList/GListItem';
+import { GListItemContent, GListItemText } from '../../GList/GListFunctionalComponent';
//
export default {
@@ -28,33 +32,23 @@ export const GComboboxSingleSelectNoChips = () => ({
data() {
return {
items: [
- {text: 'Jason Oner', subtitle: "Jason the ant", value: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'},
+ {text: 'Jason', subtitle: "Jason the ant", value: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'},
{text: 'Ranee Carlson', value: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'},
{text: 'Cindy Baker', value: 'https://cdn.vuetifyjs.com/images/lists/3.jpg'},
{text: 'Ali Connors', value: 'https://cdn.vuetifyjs.com/images/lists/4.jpg'},
],
- selected: 'sdf'
+ selected: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'
}
},
template: `
{{selected}}
+ returnObject
+ itemText="text"
+ itemValue="value"
+ v-model="selected" >
+
`,
})
export const GComboboxSingleSelectChips = () => ({
@@ -85,7 +79,7 @@ export const GComboboxSingleSelectChips = () => ({
{text: 'Cindy Baker', value: 'https://cdn.vuetifyjs.com/images/lists/3.jpg'},
{text: 'Ali Connors', value: 'https://cdn.vuetifyjs.com/images/lists/4.jpg'},
],
- selected: 'kk'
+ selected: 'll'
}
},
template: `
@@ -113,7 +107,7 @@ export const GComboboxSingleSelectChips = () => ({
`,
})
export const GComboboxMultiSelect = () => ({
- components: {GCombobox},
+ components: {GCombobox,},
props: {
chips: {default: boolean('chips', false)},
smallChips: {default: boolean('smallChips', false)},
@@ -148,7 +142,7 @@ export const GComboboxMultiSelect = () => ({
:deletableChips="deletableChips"
:menuProps="menuProps"
multiple
- clearable>
+ clearable/>
`,
})
export const GComboboxMultiSelectAllowDuplicates = () => ({
@@ -286,12 +280,41 @@ export const GComboboxPrimitiveArray = () => ({
template: `
{{selected}}
-
+
+
+
+
`,
+})
+export const GComboboxNormalizeProps = () => ({
+ components: {GCombobox, GListItem, GListItemContent, GListItemText},
+ props: {},
+ data() {
+ return {
+ items: [{ a: 1, b: () => 1 }, { a: 2, b: () => 2 }, { a: 3, b: () => 3 }],
+ selected: () => 4,
+ normalize: (value, items, isFromInput) => {
+ // value from input
+ //if (isFromInput) return { a: value, b: eval(`() => ${value}`) };
+ if (isFromInput) return { a: value, b: eval(`() => ${value}`) };
+ // value in items
+ const found = items.find(i => value && i.b.toString() === value.toString());
+ if (found) return found;
+ // value from v-model but not in items
+ return { a: value(), b: value };
+ },
+ }
+ },
+ computed:{
+ selectionString () {return this.selected.toString()}
+ },
+ template: `
+
+ {{selectionString}}
+
`,
})
-
export const test2 = () => ({
components: {},
setup() {
@@ -301,12 +324,6 @@ export const test2 = () => ({
}
})
-// testing
-import Vue from 'vue/dist/vue.common.js'
-import GCombobox from "../GCombobox";
-import GListItem from "../../GList/GListItem";
-import {GListItemContent, GListItemText} from "../../GList/GListFunctionalComponent";
-
describe('test', function () {
it('should', function () {
const vm = new Vue(test1()).$mount();
diff --git a/src/components/GCombobox/eventHandlersFactory.js b/src/components/GCombobox/eventHandlersFactory.js
new file mode 100644
index 00000000..e7611cd0
--- /dev/null
+++ b/src/components/GCombobox/eventHandlersFactory.js
@@ -0,0 +1,83 @@
+import { keyCodes } from '../../utils/helpers';
+
+export function getInputEventHandlers(props, context, state, selectedItem, lazySearch, searchText, toggleItem) {
+ const isInputDisplay = !props.multiple && !(props.chips || props.smallChips || props.deletableChips)
+
+ function onChipCloseClick(index = null) {
+ let _value = props.multiple ? selectedItem.value.splice(index, 1) : null
+ context.emit('input', _value)
+ }
+
+ function clearSelection() {
+ if (props.component !== 'select')
+ context.emit('input', props.multiple ? [] : '')
+ }
+
+ function onInputKeyDown(e) {
+ if (props.component !== 'select') resetSelectionsDisplay(state)
+ if (e.keyCode === keyCodes.down) {
+ const listRef = context.refs.menu.$refs.list
+ listRef.$el.getElementsByClassName('g-list-item')[0].focus()
+ }
+ }
+
+ function onInputChange(text) {
+ if (props.component === 'select') return
+ lazySearch.value = text
+ }
+
+ function onInputClick() {
+ resetSelectionsDisplay(state)
+ state.isFocused = true
+ }
+
+ function onInputBlur() {
+ state.isFocused = false
+ resetSelectionsDisplay(state)
+ }
+
+ function onInputDelete() {
+ if (isInputDisplay) return
+ if (searchText.value) {
+ return state.pressDeleteTimes = 0
+ } else {
+ if (state.pressDeleteTimes === 0) {
+ state.pressDeleteTimes++
+ state.lastItemColor = '#1867c0 '
+ }
+ if (state.pressDeleteTimes === 1) {
+ return state.pressDeleteTimes++
+ }
+ if (state.pressDeleteTimes === 2) {
+
+ if (props.multiple) {
+ selectedItem.value.pop()
+ context.emit('input', selectedItem.value)
+ } else {context.emit('input', null)}
+ return state.pressDeleteTimes
+ }
+ }
+ }
+
+ const inputAddSelection = () => {
+ if (props.component !== 'combobox') return
+ if (lazySearch.value.trim().length > 0) {
+ toggleItem((parseInt(lazySearch.value) || lazySearch.value))
+ lazySearch.value = ''
+ }
+ }
+
+ return {
+ onChipCloseClick, clearSelection, onInputKeyDown, onInputClick, onInputBlur, onInputDelete, inputAddSelection, onInputChange
+ }
+
+}
+
+export function resetSelectionsDisplay(state) {
+ state.pressDeleteTimes = 0
+ state.lastItemColor = '#1d1d1d'
+}
+
+
+
+
diff --git a/src/components/GCombobox/selectComponentHOC.js b/src/components/GCombobox/selectComponentHOC.js
new file mode 100644
index 00000000..cf4372b8
--- /dev/null
+++ b/src/components/GCombobox/selectComponentHOC.js
@@ -0,0 +1,361 @@
+import GList from '../GList/GList';
+import GMenu from '../GMenu/GMenu';
+import { getSelectionText, makeListSelectable2 } from '../GList/listSelectFactory';
+import { computed, reactive, ref } from '@vue/composition-api';
+import { getInputEventHandlers } from './eventHandlersFactory';
+import GTextField from '../GInput/GTextField';
+import GChip from '../GChip/GChip';
+import GIcon from '../GIcon/GIcon';
+
+const componentsFactory = (component, componentName) => {
+ return {
+ name: `${componentName}`,
+ props: {
+ component: {
+ type: String,
+ default: component
+ },
+ //select props
+ width: [String, Number],
+ //text field's props
+ ...{
+
+ //textfield style
+ ...{
+ filled: Boolean,
+ solo: Boolean,
+ outlined: Boolean,
+ flat: Boolean,
+ rounded: Boolean,
+ shaped: Boolean,
+ dense: Boolean
+ },
+ //textfield parts
+ clearable: Boolean,
+ hint: String,
+ persistent: Boolean,
+ counter: {
+ type: [Boolean, Number, String],
+ default: false
+ },
+ placeholder: String,
+ label: String,
+ prefix: String,
+ suffix: String,
+ appendIcon: String,
+ prependIcon: String,
+ prependInnerIcon: String,
+ appendInnerIcon: String,
+ clearIcon: {
+ type: String,
+ default: 'clear'
+ },
+ clearIconColor: String,
+ rules: Array,
+ type: {
+ type: String,
+ default: 'text'
+ }
+
+ },
+
+ //list props
+ searchable: {
+ type: Boolean,
+ default: true
+ },
+ multiple: Boolean,
+ allowDuplicates: Boolean,
+ //menu props
+ menuProps: {
+ type: Object,
+ default: () => ({
+ closeOnClick: true,
+ closeOnContentClick: false,
+ maxHeight: 300,
+ offsetY: true,
+ offsetOverflow: true,
+ top: false,
+ })
+ },
+ eager: Boolean,
+ //item textfieldValue props
+ chips: Boolean,
+ smallChips: Boolean,
+ deletableChips: Boolean,
+ items: {
+ type: Array,
+ default: () => []
+ },
+ itemText: {
+ type: [String, Array, Function],
+ default: 'text'
+ },
+ itemValue: {
+ type: [String, Array, Function],
+ default: 'value'
+ },
+ value: null,
+ returnObject: Boolean,
+ searchText: String,
+ genContent: Function,
+ genActivator: Function,
+
+ },
+ components: { GList, GMenu },
+ setup: function (props, context) {
+ const { getText, getValue, listType, toggleItem, normalize } = makeListSelectable2(props, context)
+
+ //menu content lazy by default, preload selectedValue
+ const selectedValue = ref(props.value)
+ //watch(() => props.value, () => selectedValue.value = props.value)
+
+ const selectionTexts = getSelectionText(props, selectedValue, listType, getText, getValue)
+
+ const lazySearch = ref('')
+
+ const tfValue = computed(() => {
+ if (props.component === 'select') return selectionTexts.value.join(', ')
+ return (props.component !== 'select' && !(props.multiple || props.chips || props.smallChips || props.deletableChips)) ? selectionTexts.value.join('') : lazySearch.value
+
+ })
+
+ //for textField validation and state calculation in case textField doesn't have value itself
+ const prependText = computed(() => {
+ if (props.component === 'select') return ''
+ return selectionTexts.value.join('')
+ })
+
+ const state = reactive({
+ searchText: '',
+ lastItemColor: '#1d1d1d',
+ pressDeleteTimes: 0,
+ isFocused: false,
+ showOptions: false
+ })
+
+ const listSearchText = computed(() => {
+ if (lazySearch.value === selectionTexts.value.join('')) return ''
+ return lazySearch.value
+ })
+
+
+ const {
+ onChipCloseClick,
+ clearSelection,
+ onInputKeyDown,
+ onInputClick,
+ onInputBlur,
+ onInputDelete,
+ onInputChange,
+ inputAddSelection,
+
+ } = getInputEventHandlers(props, context, state, selectedValue, lazySearch, listSearchText, toggleItem)
+
+ const selectableList = ref(props.items)
+
+ const genList = (state) => {
+ const onClickItem = () => {
+ state.showOptions = props.multiple
+ }
+ return {
+ context.emit('input', e)
+ },
+ 'update:selectedValue': e => {
+ selectedValue.value = e
+ context.emit('list update value')
+ },
+ 'update:list': e => selectableList.value = e,
+ },
+ scopedSlots: {
+ content: () => context.slots.item ? context.slots.item() : null,
+ prepend: ({ isSelected, item }) => context.slots.itemPrepend && context.slots.itemPrepend({ isSelected, item }),
+ }
+ }
+ }
+ ref="list"
+ />
+ }
+
+ const searchFocused = ref(false)
+ const genSearchField = () => {
+ return lazySearch.value = e}
+ value={listSearchText.value}
+ clearable
+ ref="searchText"
+ autofocus={searchFocused.value}
+ vOn:keydown={onInputKeyDown}
+ style="margin-bottom: 0; background-color: transparent"
+ />
+ }
+
+ function genNoDataSlot() {
+ if (!selectableList.value.length) return
+ {context.slots['no-data'] && context.slots['no-data']()}
+
+
+ }
+
+ const genMenuContent = (typeof props.genContent === 'function' && props.genContent) || function (state) {
+ return [
+ props.component === 'select' && props.searchable ? genSearchField() : null,
+ context.slots['prepend-item'] && context.slots['prepend-item'](),
+ genNoDataSlot(),
+ genList(state),
+ context.slots['append-item'] && context.slots['append-item']()
+ ]
+ }
+
+ //genTextField
+ const genSelectionSlot = () => {
+ return selectionTexts.value.map((item, index) => {
+ //chips
+ if (props.chips || props.smallChips || props.deletableChips || props.allowDuplicates) return onChipCloseClick(index)}>{item}
+
+ //multiple in 3 component no chips
+ else if (props.multiple) {
+ if (index === selectionTexts.value.length - 1) {
+ if (props.component === 'select') return {item}
+ return {item + ', '}
+ }
+ return {item + ', '}
+ }
+ //single in select
+ else if (props.component === 'select') return selectionTexts.value.join('')
+ }
+ )
+
+
+ }
+
+ const textFieldScopedSlots = {
+ ...context.slots['append-inner'] && {
+ 'append-inner': ({ iconColor }) =>
+ [arrow_drop_down,
+ context.slots['append-inner'] && context.slots['append-inner']()]
+ },
+ ...context.slots['append-outer'] && { 'append-outer': () => context.slots['append-outer']() },
+ 'input-slot': () =>
+
+ {genSelectionSlot()}
+ ,
+ }
+
+
+//todo: v-model textField
+ const genTextField = (typeof props.genActivator === 'function' && props.genActivator) ||
+ function (toggleContent) {
+ function inputClick() {
+ searchFocused.value = true
+ }
+
+ return (
+
+ )
+ }
+
+
+ const defaultMenuProps = {
+ closeOnClick: true,
+ closeOnContentClick: false,
+ maxHeight: 300,
+ offsetY: true,
+ offsetOverflow: true,
+ top: false,
+ }
+
+
+ function genMenu(state) {
+ const nudgeBottom = computed(() => !!props.hint ? '22px' : '2px')
+ return genTextField(toggleContent),
+ default: () => genMenuContent(state)
+ },
+ on: {
+ input: (e) => state.showOptions = state.isFocused ? true : e,
+ },
+
+ }} ref='menu'
+ />
+
+ }
+
+ function genComponent() {
+ return
+ {genMenu(state)}
+
+ }
+
+ return {
+ genComponent,
+ selectedValue,
+ selectionTexts,
+ listType,
+ prependText,
+ tfValue,
+ lazySearch,
+ listSearchText,
+ state,
+ selectableList
+
+ }
+ },
+ render() {
+ return this.genComponent()
+ }
+ }
+}
+export default componentsFactory
+
diff --git a/src/components/GCombobox/selectableComponentFactory.js b/src/components/GCombobox/selectableComponentFactory.js
new file mode 100644
index 00000000..4a0db01e
--- /dev/null
+++ b/src/components/GCombobox/selectableComponentFactory.js
@@ -0,0 +1,259 @@
+import { getSelectionText, makeListSelectable2 } from '../GList/listSelectFactory';
+import { computed, reactive, ref } from '@vue/composition-api'
+import GMenu from '../GMenu/GMenu';
+import GList from '../GList/GList';
+import GTextField from '../GInput/GTextField';
+import GIcon from '../GIcon/GIcon';
+import GChip from '../GChip/GChip';
+import { getInputEventHandlers } from './eventHandlersFactory';
+
+export function SelectableComponent(props, context) {
+
+ const { getText, getValue, listType, toggleItem, normalize } = makeListSelectable2(props, context)
+
+ //menu content lazy by default, preload selectedValue
+ const selectedValue = ref(props.value)
+ //watch(() => props.value, () => selectedValue.value = props.value)
+
+ const selectionTexts = getSelectionText(props, selectedValue, listType, getText, getValue)
+
+ const lazySearch = ref('')
+
+ const tfValue = computed(() => {
+ if (props.component === 'select') return selectionTexts.value.join(', ')
+ return (props.component !== 'select' && !(props.multiple || props.chips || props.smallChips || props.deletableChips)) ? selectionTexts.value.join('') : lazySearch.value
+
+ })
+
+ //for textField validation and state calculation in case textField doesn't have value itself
+ const prependText = computed(() => {
+ if (props.component === 'select') return ''
+ return selectionTexts.value.join('')
+ })
+
+ const state = reactive({
+ searchText: '',
+ lastItemColor: '#1d1d1d',
+ pressDeleteTimes: 0,
+ isFocused: false,
+ showOptions: false
+ })
+
+ const listSearchText = computed(() => {
+ if (lazySearch.value === selectionTexts.value.join('')) return ''
+ return lazySearch.value
+ })
+
+
+ const {
+ onChipCloseClick,
+ clearSelection,
+ onInputKeyDown,
+ onInputClick,
+ onInputBlur,
+ onInputDelete,
+ onInputChange,
+ inputAddSelection,
+
+ } = getInputEventHandlers(props, context, state, selectedValue, lazySearch, listSearchText, toggleItem)
+
+ const selectableList = ref(props.items)
+
+ const genList = (state) => {
+ const onClickItem = () => {
+ state.showOptions = props.multiple
+ }
+ return {
+ context.emit('input', e)
+ },
+ 'update:selectedValue': e => {
+ selectedValue.value = e
+ context.emit('list update value')
+ },
+ 'update:list': e => selectableList.value = e,
+ },
+ scopedSlots: {
+ content: () => context.slots.item ? context.slots.item() : null,
+ prepend: ({ isSelected, item }) => context.slots.itemPrepend && context.slots.itemPrepend({ isSelected, item }),
+ }
+ }
+ }
+ ref="list"
+ />
+ }
+
+ const searchFocused = ref(false)
+ const genSearchField = () => {
+ return lazySearch.value = e}
+ value={listSearchText.value}
+ clearable
+ ref="searchText"
+ autofocus={searchFocused.value}
+ vOn:keydown={onInputKeyDown}
+ style="margin-bottom: 0; background-color: transparent"
+ />
+ }
+
+ function genNoDataSlot() {
+ if (!selectableList.value.length) return
+ {context.slots['no-data'] && context.slots['no-data']()}
+
+
+ }
+
+ const genMenuContent = (typeof props.genContent === 'function' && props.genContent) || function (state) {
+ return [
+ props.component === 'select' && props.searchable ? genSearchField() : null,
+ context.slots['prepend-item'] && context.slots['prepend-item'](),
+ genNoDataSlot(),
+ genList(state),
+ context.slots['append-item'] && context.slots['append-item']()
+ ]
+ }
+
+ //genTextField
+ const genSelectionSlot = () => {
+ return selectionTexts.value.map((item, index) => {
+ //chips
+ if (props.chips || props.smallChips || props.deletableChips || props.allowDuplicates) return onChipCloseClick(index)}>{item}
+
+ //multiple in 3 component no chips
+ else if (props.multiple) {
+ if (index === selectionTexts.value.length - 1) {
+ if (props.component === 'select') return {item}
+ return {item + ', '}
+ }
+ return {item + ', '}
+ }
+ //single in select
+ else if (props.component === 'select') return selectionTexts.value.join('')
+ }
+ )
+
+
+ }
+
+ const textFieldScopedSlots = {
+ ...context.slots['append-inner'] && {
+ 'append-inner': ({ iconColor }) =>
+ [arrow_drop_down,
+ context.slots['append-inner'] && context.slots['append-inner']()]
+ },
+ ...context.slots['append-outer'] && { 'append-outer': () => context.slots['append-outer']() },
+ 'input-slot': () =>
+
+ {genSelectionSlot()}
+ ,
+ }
+
+
+//todo: v-model textField
+ const genTextField = (typeof props.genActivator === 'function' && props.genActivator) ||
+ function (toggleContent) {
+ function inputClick() {
+ searchFocused.value = true
+ }
+
+ return (
+
+ )
+ }
+
+
+ const defaultMenuProps = {
+ closeOnClick: true,
+ closeOnContentClick: false,
+ maxHeight: 300,
+ offsetY: true,
+ offsetOverflow: true,
+ top: false,
+ }
+
+
+ function genMenu(state) {
+ const nudgeBottom = computed(() => !!props.hint ? '22px' : '2px')
+ return genTextField(toggleContent),
+ default: () => genMenuContent(state)
+ },
+ on: {
+ input: (e) => state.showOptions = state.isFocused ? true : e,
+ },
+
+ }} ref='menu'
+ />
+
+ }
+
+ function genComponent() {
+ return
+ {genMenu(state)}
+
+ }
+
+ return {
+ genComponent,
+ selectedValue,
+ selectionTexts,
+ listType,
+ prependText,
+ tfValue,
+ lazySearch,
+ listSearchText,
+ state,
+ selectableList
+
+ }
+}
diff --git a/src/components/GInput/GInput.js b/src/components/GInput/GInput.js
deleted file mode 100644
index c7f0ee0f..00000000
--- a/src/components/GInput/GInput.js
+++ /dev/null
@@ -1,79 +0,0 @@
-//todo: setup return function (even handler, slot generate) return props class (use getVModel)
-// todo: lazy value, internalValue, common event handler, watcher
-
-import {computed, createElement, ref, watch} from '@vue/composition-api';
-import getVModel from '../../mixins/getVModel';
-import _ from 'lodash';
-
-const props = {
- label: String,
- disabled: Boolean,
- readOnly: Boolean,
- value: null,
- rules: Function,
- appendIcon: String,
- prependIcon: String,
- hasMouseDown: Boolean
-}
-
-export default function getGInput(props, context) {
-
- const state = {
- hasMouseDown: false,
- }
- // let lazyValue = ref(props.value);
- // let isValidInput = ref(false);
-
- //todo: internal value, watcher to validate content
- //event listen function
- function onClick(event) {
- context.emit('click', event)
- }
-
- function onMouseDown(event) {
- state.hasMouseDown = true
- context.emit('mousedown', event)
- }
-
- function onMouseUp(event) {
- if (state.hasMouseDown) {
- state.hasMouseDown = false
- context.emit('mouseup', event)
- }
- }
-
- function onChange(event) {
- context.emit('change', event)
- }
-
- // function onInput(event) {
- // internalValue.value = event.target.value;
- // }
-
- const listeners = {
- onClick,
- onMouseDown,
- onMouseUp,
- onChange,
- // onInput,
- }
-
- //computed state
- const isDisabled = computed(() => props.disable)
- const hasLabel = computed(() => props.label || context.slots.label)
- // todo: move to field input mixin
- // let isLabelActive = computed()
-
-
- return {
- listeners,
- state,
- isDisabled,
- hasLabel,
- // isDirty,
- // isValidInput,
- // lazyValue
- }
-
-
-}
diff --git a/src/components/GInput/GInputFactory.js b/src/components/GInput/GInputFactory.js
index 068a32e1..32ce06c1 100644
--- a/src/components/GInput/GInputFactory.js
+++ b/src/components/GInput/GInputFactory.js
@@ -1,7 +1,7 @@
export function getLabel(context, props, internalValue, isValidInput, isFocused,
labelActiveClass = 'g-tf-label__active') {
//Activate label
- const isDirty = computed(() => !!internalValue.value)
+ const isDirty = computed(() => !!internalValue.value || internalValue.value === 0)
const isLabelActive = computed(() => {
const datetimeInputTypes = ['date', 'datetime', 'datetime-local', 'month', 'time', 'week']
@@ -49,10 +49,7 @@ export function getLabel(context, props, internalValue, isValidInput, isFocused,
return {labelClasses, labelStyles, isDirty, isLabelActive, prefixRef}
}
-import {computed, reactive, ref, watch} from '@vue/composition-api';
-
-
-import {convertToUnit, keyCodes} from '../../utils/helpers';
+import { computed, reactive, ref, watch } from '@vue/composition-api';
export function getValidate(props, isFocused, internalValue, isValidInput, customAlert) {
//Validation
@@ -192,7 +189,7 @@ export function getInternalValue(props, context) {
// text field internalValue
const rawInternalValue = ref(props.value || '');
- watch(() => props.value, () => rawInternalValue.value = props.value, {lazy: true});
+ watch(() => props.value, () => rawInternalValue.value = props.value);
const internalValue = computed({
diff --git a/src/components/GInput/GTextField.vue b/src/components/GInput/GTextField.vue
index 657600b8..fc9d54ed 100644
--- a/src/components/GInput/GTextField.vue
+++ b/src/components/GInput/GTextField.vue
@@ -24,7 +24,7 @@
:style="inputErrStyles"
:type="type"
:label="label"
- v-model="internalValue"
+ v-model="internalValue "
:placeholder="placeholder"
:readonly="readOnly"
ref="input"
@@ -43,7 +43,7 @@
{{suffix}}
- {{clearIcon}}
+ {{clearIcon}}
@@ -55,7 +55,7 @@
{{hint}}
-
+
{{internalValue.length}} / {{counter}}
@@ -73,9 +73,8 @@
-
-
diff --git a/src/components/GList/GListItem.vue b/src/components/GList/GListItem.vue
index 84f635a7..9406076f 100644
--- a/src/components/GList/GListItem.vue
+++ b/src/components/GList/GListItem.vue
@@ -5,16 +5,16 @@
diff --git a/src/components/GSelect/GSelectFactory.js b/src/components/GSelect/GSelectFactory.js
deleted file mode 100644
index 5b83b2d8..00000000
--- a/src/components/GSelect/GSelectFactory.js
+++ /dev/null
@@ -1,150 +0,0 @@
-import { computed } from '@vue/composition-api';
-import _ from 'lodash';
-
-function createItemFn(prop) {
- return typeof prop === 'function'
- ? prop
- : item => {
- if (!_.isObject(item)) return item
-
- if (_.isArray(prop)) {
- const key = prop.find(Object.keys(item).includes)
- return item[key]
- } else {
- return item[prop]
- }
- }
-}
-
-const listMultipleFilter = (props, selectedValue) => {
- const itemValueFn = computed(() => createItemFn(props.itemValue))
- const itemTextFn = computed(() => createItemFn(props.itemText))
-
- let _options
- if (!selectedValue.value) {
- return _options = props.items
- }
- if (props.allowDuplicates) {
- _options = props.items;
- } else {
- if (props.returnObject) {
- _options = props.items.filter(item => !selectedValue.value.find(_selectedValue => itemTextFn.value(_selectedValue) === itemTextFn.value(item)));
- } else {
- if (props.itemValue) {
- _options = props.items.filter(item => !selectedValue.value.find(el => el === itemValueFn.value(item)))
- } else {
- _options = props.items.filter(item => !(selectedValue.value.includes(item)))
- }
- }
- }
- return _options
-}
-
-const searchTextFilteredItems = (props, state, items) => {
- const itemTextFn = computed(() => createItemFn(props.itemText))
-
- if (!state.searchText || !state.searchText.trim()) {
- return items;
- }
- if (items === null) {
- return
- }
- // normalize search text if used in g-select
- const searchText = !props.filter ? state.searchText.trim().toLowerCase() : state.searchText.trim();
- //match searchText
- let _filteredOptions
- if (!props.filter) {
- let _searchedOptions = items.filter(item => {
- const text = itemTextFn.value(item) ? (itemTextFn.value(item) + "").toLowerCase() : (item + "").toLowerCase();
- return text.startsWith(searchText);
- });
- _filteredOptions = _searchedOptions.concat(items.filter(item => {
- const text = itemTextFn.value(item) ? (itemTextFn.value(item) + "").toLowerCase() : (item + "").toLowerCase();
- return !text.startsWith(searchText) && text.includes(searchText);
- }));
- }
- //use props.filter to filter items
- else if (typeof props.filter === 'function') {
- _filteredOptions = items.filter(item => props.filter(itemTextFn.value(item), searchText))
- }
- return _filteredOptions
-}
-
-export function getList(props, selectedValue, state) {
- return computed(() => {
- if (props.multiple) {
- let options = listMultipleFilter(props, selectedValue)
-
- if (props.searchable) {
- let items = _.cloneDeep(options);
- return searchTextFilteredItems(props, state, items)
- }
- return options
- }
- if (props.searchable) return searchTextFilteredItems(props, state, _.cloneDeep(props.items))
- return props.items
- })
-}
-
-
-//selectedValue : primitive array --> return item itself,
-//selectedValue: primitive array of value --> return item have value
-//selectedValue: object array --> return item match
-//then normalise item in form {text:, value:}
-export function getSelections(props, selectedValue) {
- const itemTextFn = computed(() => createItemFn(props.itemText))
- const itemValueFn = computed(() => createItemFn(props.itemValue))
-
- const isObjectList = props.items.some(item => _.isObject(item) === true)
- return computed(() => {
- if (!props.multiple) {
- let item = selectedValue.value;
- if (!item && item !== 0) return null;
- if (!isObjectList) return item;
- if (props.itemValue && !props.returnObject) item = props.items.find(_item => itemValueFn.value(_item) === item);
- //TODO: temporary fix, needs optimizing, Function in selectedValue is converted to Object -> _.equal doesn't work
- else item = props.items.find(_item => itemTextFn.value(_item) === itemTextFn.value(item))
- return item ? {text: itemTextFn.value(item), value: itemValueFn.value(item)} : '';
- }
- const list = selectedValue.value
- if (!isObjectList) return list.map(item => props.items.find(el => el === item))
- if (props.returnObject) {
- if (props.itemValue) return list.map(item => ({text: itemTextFn.value(item), value: itemValueFn.value(item)}))
- return list.map(item => props.items.find(el => _.isEqual(el, item)))
- } else if (props.itemValue) return list.map(item => props.items.find(el => itemValueFn.value(el) === item))
- return list.map(item => props.items.find(el => _.isEqual(el, item)))
- })
-}
-
-//same as getSelection but accept selections not in list
-export function getSelectionsForCombobox(props, selectedValue) {
- const itemTextFn = computed(() => createItemFn(props.itemText))
- const itemValueFn = computed(() => createItemFn(props.itemValue))
-
- if (props.items === null || props.items.length === 0) {
- let empty = props.multiple ? [] : ''
- return selectedValue.value || empty
- }
- const isObjectList = props.items.some(item => _.isObject(item) === true)
- if (!props.multiple) {
- let item = selectedValue.value;
- if (!item && item !== 0) return null
- if (!isObjectList) return item;
- if (props.itemValue && !props.returnObject) {
- item = props.items.find(_item => itemValueFn.value(_item) === item) || item
- } else item = props.items.find(_item => _.isEqual(item, _item)) || item
- return item ? {text: itemTextFn.value(item), value: itemValueFn.value(item)} : ''
- } else {
- const list = selectedValue.value || []
- if (!isObjectList) return list
- if (props.returnObject) {
- if (props.itemValue) return list.map(item => itemValueFn.value(item) ? {
- text: itemTextFn.value(item),
- value: itemValueFn.value(item)
- } : item)
- return list
- } else if (props.itemValue) return list.map(item => props.items.find(el => itemValueFn.value(el) === item) || item)
- return list
- }
-
-}
diff --git a/src/components/GSelect/__story__/GSelect.stories.js b/src/components/GSelect/__story__/GSelect.stories.js
index 078555ac..6fb054f8 100644
--- a/src/components/GSelect/__story__/GSelect.stories.js
+++ b/src/components/GSelect/__story__/GSelect.stories.js
@@ -1,5 +1,9 @@
-import {boolean, number, text, withKnobs} from '@storybook/addon-knobs';
-import {action} from '@storybook/addon-actions'
+import { boolean, number, text, withKnobs } from '@storybook/addon-knobs';
+// testing
+import Vue from 'vue/dist/vue.common.js'
+import GListItem from '../../GList/GListItem';
+import { GListItemContent, GListItemText } from '../../GList/GListFunctionalComponent';
+import GSelect from '../GSelect';
//
export default {
@@ -23,7 +27,7 @@ export const GSelectSingle = () => ({
persistent: {default: boolean('persistent', false)},
counter: {type: [String, Number], default: number('counter', 25)},
itemText: {default: text('itemText', 'text')},
- itemValue: {default: text('itemValue', 'value')},
+ itemValue: {default: text('itemValue', '')},
chips: {default: boolean('chips', false)},
smallChips: {default: boolean('smallChips', false)},
mandatory: {default: boolean('mandatory', false)},
@@ -37,7 +41,7 @@ export const GSelectSingle = () => ({
{text: 'Cindy Baker', value: 'https://cdn.vuetifyjs.com/images/lists/3.jpg'},
{text: 'Ali Connors', value: 'https://cdn.vuetifyjs.com/images/lists/4.jpg'},
],
- selected: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'
+ selected: {text: 'Jason Oner', value: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'}
}
},
template: `
@@ -132,20 +136,20 @@ export const GSelectMultiple = () => ({
allowDuplicates: {type: Boolean, default: boolean('allow duplicates', false)},
chips: {default: boolean('chips', false)},
itemText: {default: text('itemText', 'text')},
- itemValue: {default: text('itemValue', 'value')},
+ itemValue: {default: text('itemValue', 'value2')},
clearable: {default: boolean('clearable', false)},
- returnObject: {default: boolean('returnObject', true)}
+ returnObject: {default: boolean('returnObject', false)}
},
data() {
return {
items: [
- {text: 'Jason Oner', value: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'},
- {text: 'Ranee Carlson', value: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'},
- {text: 'Cindy Baker', value: 'https://cdn.vuetifyjs.com/images/lists/3.jpg'},
- {text: 'Ali Connors', value: 'https://cdn.vuetifyjs.com/images/lists/4.jpg'},
+ {text: 'Jason Oner', value2: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'},
+ {text: 'Ranee Carlson', value2: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'},
+ {text: 'Cindy Baker', value2: 'https://cdn.vuetifyjs.com/images/lists/3.jpg'},
+ {text: 'Ali Connors', value2: 'https://cdn.vuetifyjs.com/images/lists/4.jpg'},
],
- selected: [ {text: 'Jason Oner', value: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'},
- {text: 'Ranee Carlson', value: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'},]
+ selected: [ {text: 'Jason Oner', value2: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'},
+ {text: 'Ranee Carlson', value2: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'},]
}
},
template: `
@@ -223,10 +227,10 @@ export const GSelectSearchableSingleSelect = () => ({
data() {
return {
items: [
- {text: 'Jason Oner', value: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'},
- {text: 'Ranee Carlson', value: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'},
- {text: 'Cindy Baker', value: 'https://cdn.vuetifyjs.com/images/lists/3.jpg'},
- {text: 'Ali Connors', value: 'https://cdn.vuetifyjs.com/images/lists/4.jpg'},
+ 'Jason Oner',
+ 'Ranee Carlson',
+ 'Cindy Baker',
+ 'Ali Connors',
],
selected: null
}
@@ -429,16 +433,6 @@ export const test2 = () => ({
}
})
-// testing
-import Vue from 'vue/dist/vue.common.js'
-
-import GCheckbox from "../../GCheckbox/GCheckbox";
-import GTextField from "../../GInput/GTextField";
-import GListItem from "../../GList/GListItem";
-import {GListItemText, GListItemContent, GListItemSubText} from "../../GList/GListFunctionalComponent";
-import GDivider from "../../GLayout/GDivider";
-import GSelect from "../GSelect";
-
describe('test', function () {
it('should', function () {
const vm = new Vue(test1()).$mount();