From 296edc7ec88488ee05c3cafbb1ebd9fb44110d73 Mon Sep 17 00:00:00 2001 From: Pay Duyen Date: Sat, 21 Dec 2019 18:43:05 +0700 Subject: [PATCH 01/18] fixing select logic --- package-lock.json | 444 ++++- package.json | 15 +- .../__story__/GAutocomplete.stories.js | 8 +- src/components/GCombobox/GCombobox.vue | 5 +- .../GCombobox/__story__/GCombobox.stories.js | 4 +- .../GList/__tests__/listSelectTest.test.js | 1750 +++++++++++------ src/components/GList/groupableForList.js | 54 +- src/components/GSelect/GSelectFactory.js | 83 +- 8 files changed, 1676 insertions(+), 687 deletions(-) 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 16f619e1..6b8860a3 100644 --- a/package.json +++ b/package.json @@ -14,15 +14,15 @@ "build-storybook": "build-storybook" }, "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", @@ -54,6 +54,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", @@ -74,12 +75,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/__story__/GAutocomplete.stories.js b/src/components/GAutocomplete/__story__/GAutocomplete.stories.js index 06a7e212..42ca4cc0 100644 --- a/src/components/GAutocomplete/__story__/GAutocomplete.stories.js +++ b/src/components/GAutocomplete/__story__/GAutocomplete.stories.js @@ -43,7 +43,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 +203,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 +224,7 @@ export const GAutocompleteSingleSelectPrimitive = () => ({ 'Ali Connors', 'Ranee Carlson', ], - selected: 'Cindy Baker', + selected: 'abc', filters: [ { value: 0, diff --git a/src/components/GCombobox/GCombobox.vue b/src/components/GCombobox/GCombobox.vue index a5296db5..1029bf14 100644 --- a/src/components/GCombobox/GCombobox.vue +++ b/src/components/GCombobox/GCombobox.vue @@ -1,7 +1,7 @@ diff --git a/src/components/GInput/GTextField.vue b/src/components/GInput/GTextField.vue index 7cdd68c0..ca58f061 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" @@ -129,6 +129,10 @@ }, // basic props + prependValue: { + type: String, + default: '', + }, value: [String, Number, Array, Object], type: { type: String, @@ -142,16 +146,17 @@ const tfWrapperClasses = getTfWrapperClasses(props); const {internalValue, rawInternalValue} = getInternalValue(props, context); + const tfValue = computed(() => props.prependValue + internalValue.value) const isValidInput = ref(true) const isFocused = ref(false); - const {labelClasses, labelStyles, isDirty, isLabelActive, prefixRef} = getLabel(context, props, internalValue, isValidInput, isFocused, 'g-tf-label__active'); + const {labelClasses, labelStyles, isDirty, isLabelActive, prefixRef} = getLabel(context, props, tfValue, isValidInput, isFocused, 'g-tf-label__active'); //Activate non persistent hint const hintClasses = computed(() => (props.persistent || (isFocused.value && isValidInput.value)) ? {'g-tf-hint__active': true} : {}) //event handler function - const {errorMessages, validate} = getValidate(props, isFocused, internalValue, isValidInput); + const {errorMessages, validate} = getValidate(props, isFocused, tfValue, isValidInput); const inputErrStyles = computed(() => isValidInput.value ? {} : {'color': 'red'}) //change input border color @@ -167,7 +172,7 @@ } = getEvents(props, context, internalValue, isFocused, isValidInput, validate); //set legend width for label in outlined textfield const legendStyles = computed(() => { - if (!props.solo && props.label && (isFocused.value || internalValue.value || props.placeholder)) { + if (!props.solo && props.label && (isFocused.value || tfValue.value || props.placeholder)) { const margin = props.rounded ? (props.filled ? '24px' : '16px') : (props.shaped ? '12px' : '5px'); return { 'width': 'auto', @@ -196,6 +201,7 @@ //value internalValue, rawInternalValue, + tfValue, //calculated state isLabelActive, isFocused, diff --git a/src/components/GList/GList.vue b/src/components/GList/GList.vue index 79969997..dfcd2e50 100644 --- a/src/components/GList/GList.vue +++ b/src/components/GList/GList.vue @@ -110,6 +110,7 @@ import GImg from '../GImg/GImg'; import {keyCodes} from '../../utils/helpers'; import {makeListSelectable} from './groupableForList'; + import { makeListSelectable2 } from './listSelectFactory'; export default { name: 'GList', @@ -142,6 +143,7 @@ }, subtextWrap: Boolean, value: [String, Object, Number, Array], + externalNormalisedValue: [String, Object, Number, Array], selectable: Boolean, multiple: Boolean, mandatory: Boolean, @@ -156,6 +158,10 @@ returnObject: Boolean, svg: Boolean, appendIcon: String, + searchText: { + type: String, + default: '' + } }, setup: function (props, context) { //G list computed class @@ -244,7 +250,11 @@ provide('getListEvents', getListEvents) - const {uniqueItems: renderList, internalValue, toggleItem, isActiveItem} = makeListSelectable(props, context); + //const {uniqueItems: renderList, internalValue, toggleItem, isActiveItem} = makeListSelectable(props, context); + const {selectableList : renderList, + normalisedValue : internalValue, + toggleItem, + isActiveItem,} = makeListSelectable2(props, context) //handler case: list items in list const add = (item) => { diff --git a/src/components/GList/__story__/GList.stories.js b/src/components/GList/__story__/GList.stories.js index 5791e193..b8164a30 100644 --- a/src/components/GList/__story__/GList.stories.js +++ b/src/components/GList/__story__/GList.stories.js @@ -96,7 +96,7 @@ export const gListSingleSelectPlayGround = () => ({ prependType: { default: text('prependType', 'avatar') }, subtextWrap: { default: boolean('subtextWrap', false) }, mandatory: { default: boolean('mandatory', false) }, - itemValue: { default: text('itemValue', 'text') }, + itemValue: { default: text('itemValue', undefined) }, itemText: { default: text('itemText', 'text') }, activeClass: { default: text('activeClass', '') }, returnObject: { default: boolean('returnObject', false) }, @@ -497,7 +497,7 @@ export const gListSingleSectionSelect = () => ({ `
selectedItem: {{testValue}} - +
`, diff --git a/src/components/GList/__tests__/listSelectTest.test.js b/src/components/GList/__tests__/listSelectTest.test.js index a4db9162..5200cb37 100644 --- a/src/components/GList/__tests__/listSelectTest.test.js +++ b/src/components/GList/__tests__/listSelectTest.test.js @@ -1023,6 +1023,16 @@ describe("test", function() { }, ] `); + expect(parentVm.externalValueNormalize).toMatchInlineSnapshot(` + Array [ + Object { + "value": 1, + }, + Object { + "value": 2, + }, + ] + `); }); it("value normalize in case object array returnObject single", async function() { diff --git a/src/components/GList/__tests__/listSelectTest2.test.js b/src/components/GList/__tests__/listSelectTest2.test.js index 89c59499..49665efd 100644 --- a/src/components/GList/__tests__/listSelectTest2.test.js +++ b/src/components/GList/__tests__/listSelectTest2.test.js @@ -1,7 +1,7 @@ -import { computed, ref } from '@vue/composition-api'; +import { computed, ref, watch } from '@vue/composition-api'; import _ from 'lodash'; import Vue from 'vue/dist/vue.common.js'; -import { makeListSelectable2 } from '../listSelectFactory'; +import { getSelection2, getSelection3, makeListSelectable2 } from '../listSelectFactory'; const parentVmFactory = attrs => new Vue({ @@ -12,7 +12,7 @@ const parentVmFactory = attrs => allowDuplicates: Boolean, multiple: Boolean, returnObject: Boolean, - externalValueNormalize: null, + externalNormalisedValue: null, filter: { type: Function }, @@ -70,7 +70,21 @@ const parentVmFactory = attrs => toggleItem, isActiveItem, } = makeListSelectable2(props, context); + const valRef = ref(props.value) + watch(() => props.value, () => valRef.value = props.value) + const formattedSelection = getSelection3(props, valRef, listType, getText, getValue) + const selectionTexts = computed(() => { + if (props.multiple) { + return formattedSelection.value.map(item => { + return item ? (item['text'] ||item['value'] || item) : '' + }) + } + return formattedSelection.value || formattedSelection.value === 0 + ? formattedSelection.value['text'] || formattedSelection.value['value'] || formattedSelection.value + : '' + }) + const selectionString = computed(() => props.multiple ? selectionTexts.value.join(', ') : selectionTexts.value.toString()) const searchText = ref(''); return { getText, @@ -81,6 +95,9 @@ const parentVmFactory = attrs => normalisedValue, toggleItem, isActiveItem, + formattedSelection, + selectionTexts, + selectionString }; } } @@ -88,7 +105,7 @@ const parentVmFactory = attrs => data() { return { externalValueNormalize: null, - ...attrs + ...attrs, }; }, render(h) { @@ -98,8 +115,8 @@ const parentVmFactory = attrs => {...{ props: this.$data, on: { - 'update:externalValueNormalize': val => { - log('update:externalValueNormalize'); + 'update:externalNormalisedValue': val => { + console.log('update:externalNormalisedValue', val); this.externalValueNormalize = val; } } @@ -124,6 +141,7 @@ describe('test', function () { //expect(parentVm.child.valueNormalize).toBe({value: 2}); expect(parentVm.child.normalisedList).toEqual([1, 2, 3, 6]) expect(parentVm.child.normalisedValue).toEqual(1) + expect(parentVm.child.formattedSelection).toEqual(1) expect(parentVm.child.isActiveItem(parentVm.child.selectableList[0])).toBe(true) expect(parentVm.child.selectableList).toEqual([1, 2, 3, 6]) parentVm.child.toggleItem(parentVm.child.selectableList[0]) @@ -131,7 +149,8 @@ describe('test', function () { await parentVm.$nextTick(); expect(parentVm.child.isActiveItem(parentVm.child.selectableList[0])).toBe(false) expect(parentVm.child.normalisedValue).toEqual(undefined) - + expect(parentVm.externalValueNormalize).toEqual(undefined) + expect(parentVm.child.selectionString).toEqual('') }); it('single, primitive, mandatory', async function () { @@ -145,11 +164,13 @@ describe('test', function () { //expect(parentVm.child.valueNormalize).toBe({value: 2}); expect(parentVm.child.normalisedList).toEqual([1, 2, 3, 6]) expect(parentVm.child.normalisedValue).toEqual(1) + expect(parentVm.externalValueNormalize).toEqual(1) expect(parentVm.child.selectableList).toEqual([1, 2, 3, 6]) parentVm.child.toggleItem(parentVm.child.items[0]) await parentVm.$nextTick(); await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual(1) + expect(parentVm.externalValueNormalize).toEqual(1) }); @@ -169,6 +190,7 @@ describe('test', function () { await parentVm.$nextTick(); await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([2, 1]) + expect(parentVm.child.selectionString).toEqual('2, 1') }); @@ -212,14 +234,16 @@ describe('test', function () { it('single returnObject ', async function () { const parentVm = parentVmFactory({ - itemText: '', + itemText: 'a', itemValue: '', returnObject: true, value: { a: 1 }, items: [{ a: 1 }, { a: 2 }, { a: 3 }, { a: 3 }, { a: 6 }, { a: 6 }] }); expect(parentVm.child.normalisedValue).toEqual({ a: 1 }) + expect(parentVm.externalValueNormalize).toEqual({ a: 1 }) expect(parentVm.child.isActiveItem(parentVm.child.selectableList[0])).toBe(true) + expect(parentVm.child.selectionString).toEqual('1') expect(parentVm.child.normalisedList).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }, { a: 6 }]) expect(parentVm.child.selectableList).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }, { a: 6 }]) parentVm.child.toggleItem(parentVm.child.selectableList[1]) @@ -227,7 +251,8 @@ describe('test', function () { await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual({ a: 2 }) expect(parentVm.child.isActiveItem(parentVm.child.selectableList[0])).toBe(false) - expect(parentVm.child.isActiveItem(parentVm.child.selectableList[1])).toBe(false) + expect(parentVm.child.isActiveItem(parentVm.child.selectableList[1])).toBe(true) + }); @@ -247,6 +272,7 @@ describe('test', function () { await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual({ a: 3 }) expect(parentVm.child.selectableList).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }, { a: 6 }]) + expect(parentVm.child.selectionString).toEqual('3') }); @@ -283,10 +309,33 @@ describe('test', function () { await parentVm.$nextTick(); await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual({ a: 3 }) - + expect(parentVm.child.selectionString).toEqual('3') expect(parentVm.child.value).toEqual(3) + }); + it('single not returnObject itemValue itemText', async function () { + const parentVm = parentVmFactory({ + itemText: 'a', + itemValue: 'b', + returnObject: false, + value: 1, + items: [{ a: 1, b: 2 }, { a: 2, b: 1 }, { a: 3, b: 7 }, { a: 3, b: 7 }, { a: 6, b: 8 }, { a: 6, b: 8 }] + }); + expect(parentVm.child.normalisedValue).toEqual({ a: 2, b: 1 }) + expect(parentVm.child.value).toEqual(1) + expect(parentVm.child.formattedSelection).toEqual({text: 2, value: 1}) + expect(parentVm.child.selectionString).toEqual('2') + expect(parentVm.child.selectableList).toEqual([{ a: 1, b: 2 }, { a: 2, b: 1 }, { a: 3, b: 7 },{ a: 6, b: 8 },]) + parentVm.child.toggleItem(parentVm.child.selectableList[2]) + await parentVm.$nextTick(); + await parentVm.$nextTick(); + expect(parentVm.child.normalisedValue).toEqual({ a: 3, b: 7 }) + expect(parentVm.child.value).toEqual(7) + expect(parentVm.child.selectionString).toEqual('3') + + + }); it('multiple returnObject ', async function () { @@ -341,6 +390,7 @@ describe('test', function () { await parentVm.$nextTick(); await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }]) + expect(parentVm.child.selectionString).toEqual('1, 2, 3') }); @@ -360,6 +410,7 @@ describe('test', function () { await parentVm.$nextTick(); await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([{ a: 1 }, { a: 2 }, { a: 1 }]) + expect(parentVm.child.selectionString).toEqual('1, 2, 1') }); @@ -377,6 +428,7 @@ describe('test', function () { await parentVm.$nextTick(); await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([{ a: 1 }, { a: 2 }]) + expect(parentVm.child.selectionString).toEqual('1, 2') }); @@ -395,6 +447,7 @@ describe('test', function () { await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([{ a: 1 }, { a: 2 }, { a: 3 },]) expect(parentVm.child.value).toEqual([1, 2, 3]) + expect(parentVm.child.selectionString).toEqual('1, 2, 3') }); it('multiple not returnObject init value is value itemValue allowDuplicates ', async function () { @@ -413,6 +466,7 @@ describe('test', function () { await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([{ a: 1 }, { a: 2 }, { a: 1 }]) expect(parentVm.child.value).toEqual([1, 2, 1]) + expect(parentVm.child.selectionString).toEqual('1, 2, 1') }); it('multiple not returnObject itemText ', async function () { const parentVm = parentVmFactory({ @@ -429,6 +483,7 @@ describe('test', function () { await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([{ a: 1 }, { a: 2 }]) expect(parentVm.child.value).toEqual([1, 2]) + expect(parentVm.child.selectionString).toEqual('1, 2') }); @@ -447,6 +502,7 @@ describe('test', function () { await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([{ a: 1 }, { a: 2 }, { a: 3 },]) expect(parentVm.child.value).toEqual([1, 2, 3]) + expect(parentVm.child.selectionString).toEqual('1, 2, 3') }); it('multiple not returnObject init value is primitive itemText allowDuplicates ', async function () { @@ -465,6 +521,7 @@ describe('test', function () { await parentVm.$nextTick(); expect(parentVm.child.normalisedValue).toEqual([{ a: 1, b: 1 }, { a: 2, b: 2 }, { a: 1, b: 1 }]) expect(parentVm.child.value).toEqual([1, 2, 1]) + expect(parentVm.child.selectionString).toEqual('1, 2, 1') }); it('multiple not returnObject itemValue itemText ', async function () { const parentVm = parentVmFactory({ @@ -472,14 +529,16 @@ describe('test', function () { itemText: 'b', itemValue: 'a', value: [{ a: 1, b: 1 }], - items: [{ a: 1, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 3 }, { a: 3, b: 3 }, { a: 6, b: 6 }, { a: 6, b: 6 }] + items: [{ a: 1, b: 1 }, { a: 3, b: 2 }, { a: 3, b: 3 }, { a: 3, b: 3 }, { a: 6, b: 6 }, { a: 6, b: 6 }] }); expect(parentVm.child.normalisedValue).toEqual([{ a: 1, b: 1 }]) - expect(parentVm.child.selectableList).toEqual([{ a: 2, b: 2 }, { a: 3, b: 3 }, { a: 6, b: 6 }]) + expect(parentVm.child.selectableList).toEqual([{ a: 3, b: 2 }, { a: 3, b: 3 }, { a: 6, b: 6 }]) parentVm.child.toggleItem(parentVm.child.selectableList[0]) await parentVm.$nextTick(); await parentVm.$nextTick(); - expect(parentVm.child.normalisedValue).toEqual([{ a: 1, b: 1 }, { a: 2, b: 2 }]) + expect(parentVm.child.normalisedValue).toEqual([{ a: 1, b: 1 }, { a: 3, b: 2 }]) + expect(parentVm.child.value).toEqual([1, 3]) + expect(parentVm.child.selectionString).toEqual('1, 2') }); diff --git a/src/components/GList/listSelectFactory.js b/src/components/GList/listSelectFactory.js index 8d2258d6..b062bf61 100644 --- a/src/components/GList/listSelectFactory.js +++ b/src/components/GList/listSelectFactory.js @@ -31,8 +31,10 @@ export function makeListSelectable2(props, context) { }) const normalisedList = computed(() => { + let value = props.value + if (_.isArray(props.items)) { - return (listType.value === 'primitive') ? _.uniq(props.items) : _.uniqWith(props.items, _.isEqual) + return (listType.value === 'primitive') ? _.uniq(props.items) : _.uniqWith(props.items.map(item => _.omit(item, ['elm', 'isRootInsert'])), _.isEqual) } return [] } @@ -43,12 +45,11 @@ export function makeListSelectable2(props, context) { //todo: normalised value: map value to an item in list if it existed const normalisedValue = computed(() => { const _normalise = function (value) { - let _normalisedList = normalisedList.value.map(item => _.omit(item, ['elm', 'isRootInsert'])) if (listType.value === 'primitive') return normalisedList.value.find(item => item === value) - else if ((listType.value === 'objectReturnObject' && typeof value === 'object') || typeof value === 'object') return _normalisedList.find(item => - _.isEqual(item, _.omit(value, ['elm', 'isRootInsert']))) + else if ((listType.value === 'objectReturnObject' && typeof value === 'object') || typeof value === 'object') return normalisedList.value.find(item => + _.isEqual(_.omit(item, ['elm', 'isRootInsert']), _.omit(value, ['elm', 'isRootInsert']))) else { - return _normalisedList.find(item => getValue.value(item) === value) || _normalisedList.find(item => getText.value(item) === value) + return normalisedList.value.find(item => getValue.value(item) === value) || normalisedList.value.find(item => getText.value(item) === value) } } @@ -62,8 +63,11 @@ export function makeListSelectable2(props, context) { } } - if (!props.multiple) return normalise(props.value) - return props.value.map(normalise) + let res + if (!props.multiple) res = props.value ? normalise(props.value) : undefined + else res = props.value ? props.value.map(normalise) : [] + context.emit('update:externalNormalisedValue', res); + return res }) function unNormalise(item) { @@ -93,8 +97,7 @@ export function makeListSelectable2(props, context) { }; const updateMultiple = (item) => { - - let _normalisedVal = [...normalisedValue.value] + let _normalisedVal if (listType.value !== 'objectWithValueOrText') _normalisedVal = [...normalisedValue.value] else _normalisedVal = normalisedValue.value.map(item => getValue.value(item) || getText.value(item)) @@ -136,22 +139,22 @@ export function makeListSelectable2(props, context) { if (props.allowDuplicates) return normalisedList.value return normalisedList.value.filter(item => !normalisedValue.value.some(el => _.isEqual(el, item))) }) - const searchText = ref('') const searchFn = computed(() => { - if (_.isEmpty(searchText)) return items => items; + let searchText = props.searchText + if (_.isEmpty(searchText.trim() || searchText)) return items => items; //todo: search logic return items => { if (props.filter) { return items.filter(item => { - return props.filter(getText.value(item), searchText.value); + return props.filter(getText.value(item), searchText); }); } const searchStartsWith = items.filter(item => { - return getText.value(item).toString().toLowerCase().startsWith(searchText.value); + return getText.value(item).toString().toLowerCase().startsWith(searchText); }); const searchIncludes = items.filter(i => !searchStartsWith.includes(i)).filter(item => { - return getText.value(item).toString().toLowerCase().includes(searchText.value); + return getText.value(item).toString().toLowerCase().includes(searchText); }); return searchStartsWith.concat(searchIncludes); @@ -180,21 +183,39 @@ export function makeListSelectable2(props, context) { } -export function getSelection(props, context, selectedValue) { - const { listType, getText, getValue } = makeListSelectable2(props, context) +export function getSelection2(props, context, selectedValue, listType, getText, getValue) { return computed(() => { if (!props.multiple) { - let item = selectedValue.value + let item = selectedValue.value && selectedValue.value if (!item && item !== 0) return '' if (listType.value === 'primitive') return item else if (getText.value(item) || getValue.value(item)) return { text: getText.value(item) || '', value: getValue.value(item) || '' } - return '' + return '' } const list = selectedValue.value return list.map(item => { if (listType.value === 'primitive') return item else if (getText.value(item) || getValue.value(item)) return { text: getText.value(item) || '', value: getValue.value(item) || '' } - return '' + return '' + }) + }) +} + +export function getSelection3(props, selectedValue, listType, getText, getValue) { + return computed(() => { + if (!props.multiple) { + let item = selectedValue.value + let _item = props.items.find(el => getValue.value(el) ? getValue.value(el) === item : getText.value(el) === item) + if (!item && item !== 0) return '' + if (listType.value === 'primitive') return item + return { text: getText.value(_item || item) || '', value: getValue.value(_item || item) || '' } + } + const list = selectedValue.value || [] + return list.map(item => { + let _item = props.items.find(el => getValue.value(el) ? getValue.value(el) === item : getText.value(el) === item) + if (listType.value === 'primitive') return item + return { text: getText.value(_item || item) || '', value: getValue.value(_item || item) || '' } + }) }) } diff --git a/src/components/GSelect/GSelect.vue b/src/components/GSelect/GSelect.vue index 00451c4c..69c2531e 100644 --- a/src/components/GSelect/GSelect.vue +++ b/src/components/GSelect/GSelect.vue @@ -1,20 +1,21 @@ diff --git a/src/components/GSelect/__story__/GSelect.stories.js b/src/components/GSelect/__story__/GSelect.stories.js index 078555ac..3c6e6dd4 100644 --- a/src/components/GSelect/__story__/GSelect.stories.js +++ b/src/components/GSelect/__story__/GSelect.stories.js @@ -23,7 +23,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 +37,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: ` @@ -134,7 +134,7 @@ export const GSelectMultiple = () => ({ itemText: {default: text('itemText', 'text')}, itemValue: {default: text('itemValue', 'value')}, clearable: {default: boolean('clearable', false)}, - returnObject: {default: boolean('returnObject', true)} + returnObject: {default: boolean('returnObject', false)} }, data() { return { @@ -223,10 +223,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 } From 035703e5fae268b80e36e21688bc0fd5fc971b1b Mon Sep 17 00:00:00 2001 From: Pay Duyen Date: Mon, 30 Dec 2019 15:31:50 +0700 Subject: [PATCH 04/18] New List, select, autocomplete, combobox --- .../GAutocomplete/GAutocompleteFactory.js | 103 +++-- .../GAutocomplete/NewAutocomplete.vue | 151 +++++++ .../__story__/GAutocomplete.stories.js | 5 +- src/components/GCombobox/NewCombobox.vue | 151 +++++++ .../GCombobox/SelectableComponent.vue | 374 ++++++++++++++++++ .../GCombobox/__story__/GCombobox.stories.js | 37 +- src/components/GInput/GInputFactory.js | 2 +- src/components/GInput/GTextField.vue | 3 +- src/components/GInput/NewTf.vue | 15 + src/components/GList/GList.vue | 1 + src/components/GList/NewList.vue | 277 +++++++++++++ .../GList/__story__/GList.stories.js | 32 +- .../GList/__tests__/listSelectTest2.test.js | 53 ++- src/components/GList/listSelectFactory.js | 34 +- src/components/GSelect/GSelect.vue | 2 +- src/components/GSelect/NewSelect.vue | 135 +++++++ .../GSelect/__story__/GSelect.stories.js | 13 +- 17 files changed, 1303 insertions(+), 85 deletions(-) create mode 100644 src/components/GAutocomplete/NewAutocomplete.vue create mode 100644 src/components/GCombobox/NewCombobox.vue create mode 100644 src/components/GCombobox/SelectableComponent.vue create mode 100644 src/components/GInput/NewTf.vue create mode 100644 src/components/GList/NewList.vue create mode 100644 src/components/GSelect/NewSelect.vue diff --git a/src/components/GAutocomplete/GAutocompleteFactory.js b/src/components/GAutocomplete/GAutocompleteFactory.js index f949c17b..e9f109af 100644 --- a/src/components/GAutocomplete/GAutocompleteFactory.js +++ b/src/components/GAutocomplete/GAutocompleteFactory.js @@ -1,29 +1,34 @@ -import {keyCodes} from '../../utils/helpers'; +import { keyCodes } from '../../utils/helpers'; +import { ref } from '@vue/composition-api' + +export function getInputEventHandlers(props, context, state, selections, selectedItem, isFocused, toggleItem, showOptions) { + const isInputDisplay = !props.multiple && !(props.chips || props.smallChips || props.deletableChips) -export function getInputEventHandlers(props, context, state, selections, selectedItem, isFocused, toggleItem) { 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 && props.component === 'combobox') { + context.emit('input', '') + } context.emit('update:searchText', text) } @@ -39,9 +44,7 @@ export function getInputEventHandlers(props, context, state, selections, selecte } function onInputDelete() { - if (!props.multiple && !(props.chips || props.smallChips || props.deletableChips)) { - return - } + if (isInputDisplay) return if (state.searchText) { return state.pressDeleteTimes = 0 } else { @@ -60,15 +63,9 @@ export function getInputEventHandlers(props, context, state, selections, selecte } const inputAddSelection = () => { + if (props.component !== 'combobox') return if (state.searchText.trim().length > 0) { - let isNumberArray = props.itemValue ? props.items.some(item => typeof item[props.itemValue] === 'number') : props.items.some(item => typeof item === 'number') - let inputAddedItem; - if (props.returnObbject || props.itemValue) inputAddedItem = { - [props.itemText]: state.searchText, - [props.itemValue]: isNumberArray ? Number(state.searchText) : state.searchText - } - else inputAddedItem = isNumberArray ? Number(state.searchText) : state.searchText - toggleItem(inputAddedItem) + toggleItem(parseInt(state.searchText) || state.searchText) setSearch(props, context, selections, state) } } @@ -93,3 +90,65 @@ export function setSearch(props, context, selections, state) { state.searchText = '' }) } + +//shared render functions +// export function genMenu(props, showOptions, isFocused) { +// const nudgeBottom = computed(() => !!props.hint ? '22px' : '2px') +// return props.genActivator, +// default: () => props.genMenuContent +// }, +// on: { +// input: (e) => isFocused.value ? showOptions.value = true : showOptions.value = e, +// } +// }} +// /> +// } +// +// export function genComponent(props, showOptions) { +// let activeClass = props.component + '__active' +// return
+// {genMenu(showOptions)} +//
+// } +// +// export function genList(props, context, showOptions, selectedValue, state) { +// return showOptions.value = props.multiple, +// input: e => { +// selectedValue.value = e +// context.emit('input', e) +// }, +// }, +// scopedSlots: { +// content: () => context.slots.item && context.slots.item() +// } +// }} +// ref="list" +// /> +// } + + diff --git a/src/components/GAutocomplete/NewAutocomplete.vue b/src/components/GAutocomplete/NewAutocomplete.vue new file mode 100644 index 00000000..8269302e --- /dev/null +++ b/src/components/GAutocomplete/NewAutocomplete.vue @@ -0,0 +1,151 @@ + + + diff --git a/src/components/GAutocomplete/__story__/GAutocomplete.stories.js b/src/components/GAutocomplete/__story__/GAutocomplete.stories.js index 42ca4cc0..760f17eb 100644 --- a/src/components/GAutocomplete/__story__/GAutocomplete.stories.js +++ b/src/components/GAutocomplete/__story__/GAutocomplete.stories.js @@ -8,7 +8,7 @@ export default { } export const GAutocompleteSingleSelect = () => ({ - components: {GAutocomplete, GSelect}, + components: {GAutocomplete, GSelect, NewAutocomplete}, props: { label: {default: text('Input label', 'Label')}, placeholder: {default: text('Input placeholder', '')}, @@ -77,7 +77,7 @@ export const GAutocompleteSingleSelect = () => ({ > - ({ import Vue from 'vue/dist/vue.common.js' import GAutocomplete from "../GAutocomplete"; import GSelect from "../../GSelect/GSelect"; +import NewAutocomplete from '../NewAutocomplete'; describe('test', function () { it('should', function () { diff --git a/src/components/GCombobox/NewCombobox.vue b/src/components/GCombobox/NewCombobox.vue new file mode 100644 index 00000000..cba1cf48 --- /dev/null +++ b/src/components/GCombobox/NewCombobox.vue @@ -0,0 +1,151 @@ + + + diff --git a/src/components/GCombobox/SelectableComponent.vue b/src/components/GCombobox/SelectableComponent.vue new file mode 100644 index 00000000..95b956d2 --- /dev/null +++ b/src/components/GCombobox/SelectableComponent.vue @@ -0,0 +1,374 @@ + + diff --git a/src/components/GCombobox/__story__/GCombobox.stories.js b/src/components/GCombobox/__story__/GCombobox.stories.js index 09ee6706..4c5a8d1c 100644 --- a/src/components/GCombobox/__story__/GCombobox.stories.js +++ b/src/components/GCombobox/__story__/GCombobox.stories.js @@ -8,7 +8,7 @@ export default { } export const GComboboxSingleSelectNoChips = () => ({ - components: {GCombobox}, + components: {GCombobox, NewCombobox}, props: { label: {default: text('Input label', 'Label')}, placeholder: {default: text('Input placeholder', '')}, @@ -38,23 +38,11 @@ export const GComboboxSingleSelectNoChips = () => ({ }, template: `
- {{selected}} - + +
`, }) export const GComboboxSingleSelectChips = () => ({ @@ -113,7 +101,7 @@ export const GComboboxSingleSelectChips = () => ({ `, }) export const GComboboxMultiSelect = () => ({ - components: {GCombobox}, + components: {GCombobox, NewCombobox}, props: { chips: {default: boolean('chips', false)}, smallChips: {default: boolean('smallChips', false)}, @@ -137,7 +125,7 @@ export const GComboboxMultiSelect = () => ({ template: `
{{selected}} - ({ :deletableChips="deletableChips" :menuProps="menuProps" multiple - clearable> + clearable/>
`, }) export const GComboboxMultiSelectAllowDuplicates = () => ({ @@ -188,7 +176,7 @@ export const GComboboxMultiSelectAllowDuplicates = () => ({ `, }) export const GComboboxNoDataSlot = () => ({ - components: {GCombobox, GListItem, GListItemContent, GListItemText}, + components: {GCombobox, GListItem, GListItemContent, GListItemText, NewCombobox}, props: {}, data() { return { @@ -201,7 +189,7 @@ export const GComboboxNoDataSlot = () => ({ }, template: `
- + - +
`, }) export const GComboboxSingleWithValidate = () => ({ @@ -306,6 +294,7 @@ import Vue from 'vue/dist/vue.common.js' import GCombobox from "../GCombobox"; import GListItem from "../../GList/GListItem"; import {GListItemContent, GListItemText} from "../../GList/GListFunctionalComponent"; +import NewCombobox from '../NewCombobox'; describe('test', function () { it('should', function () { diff --git a/src/components/GInput/GInputFactory.js b/src/components/GInput/GInputFactory.js index 068a32e1..c8ffdf6e 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'] diff --git a/src/components/GInput/GTextField.vue b/src/components/GInput/GTextField.vue index ca58f061..a676f317 100644 --- a/src/components/GInput/GTextField.vue +++ b/src/components/GInput/GTextField.vue @@ -44,7 +44,7 @@
{{suffix}}
- {{clearIcon}} + {{clearIcon}} @@ -94,6 +94,7 @@ type: String, default: 'clear' }, + clearIconColor: String, prefix: String, suffix: String, //input states diff --git a/src/components/GInput/NewTf.vue b/src/components/GInput/NewTf.vue new file mode 100644 index 00000000..4126e827 --- /dev/null +++ b/src/components/GInput/NewTf.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/components/GList/GList.vue b/src/components/GList/GList.vue index dfcd2e50..d07a4df3 100644 --- a/src/components/GList/GList.vue +++ b/src/components/GList/GList.vue @@ -116,6 +116,7 @@ name: 'GList', components: {GImg, GAvatar, GIcon, GDivider}, props: { + inCombobox: Boolean, height: String, width: String, disabled: Boolean, diff --git a/src/components/GList/NewList.vue b/src/components/GList/NewList.vue new file mode 100644 index 00000000..05c5579e --- /dev/null +++ b/src/components/GList/NewList.vue @@ -0,0 +1,277 @@ + + diff --git a/src/components/GList/__story__/GList.stories.js b/src/components/GList/__story__/GList.stories.js index b8164a30..5e32bab2 100644 --- a/src/components/GList/__story__/GList.stories.js +++ b/src/components/GList/__story__/GList.stories.js @@ -14,13 +14,14 @@ import { GListItemSubText, GListHeader } from '../GListFunctionalComponent' +import NewList from '../NewList'; export default { title: 'GList', decorators: [withKnobs], }; export const gListPlayGround = () => ({ - components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader }, + components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader, NewList }, data() { return { items: [ @@ -40,7 +41,7 @@ export const gListPlayGround = () => ({ nav: { default: boolean('nav', false) }, multiSection: { default: boolean('multiSection', false) }, subheader: { default: text('subheader', 'subheader') }, - divider: { type: [String, Boolean], default: boolean('divider', false) }, + divider: { type: [String, Boolean], default: boolean('divider', true) }, prependType: { default: text('prependType', 'avatar') }, subtextWrap: { default: boolean('subtextWrap', false) }, selectable: { default: boolean('selectable', false) }, @@ -53,7 +54,7 @@ export const gListPlayGround = () => ({ }, template: ` - ({ `, }) export const gListSingleSelectPlayGround = () => ({ - components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader }, + components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader, NewList }, data() { return { items: [ @@ -80,7 +81,7 @@ export const gListSingleSelectPlayGround = () => ({ { text: 'Cindy Baker', prepend: 'https://cdn.vuetifyjs.com/images/lists/3.jpg' }, { text: 'Ali Connors', prepend: 'https://cdn.vuetifyjs.com/images/lists/4.jpg' }, ], - testValue: 'Jason' + testValue: 'Jason Oner' } }, props: { @@ -104,7 +105,7 @@ export const gListSingleSelectPlayGround = () => ({ template: `
{{testValue}} - ({ :itemText="itemText" :returnObject="returnObject" :activeClass="activeClass"> - +
`, }) export const gListMultiSelectPlayGround = () => ({ - components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader }, + components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader, NewList }, data() { return { items: [ @@ -165,7 +166,7 @@ export const gListMultiSelectPlayGround = () => ({ template: `
{{testValue}} - ({ :prependType="prependType" :subtextWrap="subtextWrap" selectable - :multiple="multiple" + multiple :mandatory="mandatory" :allowDuplicates="allowDuplicates" - :itemValue="itemValue" - :itemText="itemText" + itemValue="prepend" + itemText="text" :returnObject="returnObject" :activeClass="activeClass"> - -
- `, + +
`, }) export const gListInset = () => ({ components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader }, @@ -583,7 +583,7 @@ export const gListMultiSelect = () => ({ `
selectedItem: {{testValue}} - +
`, diff --git a/src/components/GList/__tests__/listSelectTest2.test.js b/src/components/GList/__tests__/listSelectTest2.test.js index 49665efd..ca5fb383 100644 --- a/src/components/GList/__tests__/listSelectTest2.test.js +++ b/src/components/GList/__tests__/listSelectTest2.test.js @@ -16,7 +16,7 @@ const parentVmFactory = attrs => filter: { type: Function }, - freeItemAllow: Boolean, + component: String, items: { type: Array, default: () => [] @@ -105,6 +105,7 @@ const parentVmFactory = attrs => data() { return { externalValueNormalize: null, + selection: null, ...attrs, }; }, @@ -118,6 +119,10 @@ const parentVmFactory = attrs => 'update:externalNormalisedValue': val => { console.log('update:externalNormalisedValue', val); this.externalValueNormalize = val; + }, + 'update:selection': val => { + console.log('update:selection', val); + this.selection = val; } } }} @@ -543,5 +548,51 @@ describe('test', function () { }); //todo: test getSelection + //todo: combobox test: + it('single, primitive, combobox', async function () { + const parentVm = parentVmFactory({ + itemText: 'value', + itemValue: 'value', + value: 1, + items: [1, 2, 3, 3, 6, 6], + component: 'combobox' + }); + //expect(parentVm.child.valueNormalize).toBe({value: 2}); + expect(parentVm.child.normalisedList).toEqual([1, 2, 3, 6]) + expect(parentVm.child.normalisedValue).toEqual(1) + expect(parentVm.child.formattedSelection).toEqual(1) + expect(parentVm.child.isActiveItem(parentVm.child.selectableList[0])).toBe(true) + expect(parentVm.child.selectableList).toEqual([1, 2, 3, 6]) + parentVm.child.toggleItem(7) + await parentVm.$nextTick(); + await parentVm.$nextTick(); + + expect(parentVm.child.normalisedValue).toEqual(7) + expect(parentVm.externalValueNormalize).toEqual(7) + expect(parentVm.child.selectionString).toEqual('7') + + }); + it('single not returnObject itemText, combobox', async function () { + const parentVm = parentVmFactory({ + component:'combobox', + itemText: 'a', + itemValue: 'a', + returnObject: false, + value: 9, + items: [{ a: 1 }, { a: 2 }, { a: 3 }, { a: 3 }, { a: 6 }, { a: 6 }] + }); + expect(parentVm.child.normalisedValue).toEqual(9) + expect(parentVm.child.selectableList).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }, { a: 6 }]) + parentVm.child.toggleItem(7) + await parentVm.$nextTick(); + await parentVm.$nextTick(); + expect(parentVm.child.normalisedValue).toEqual(7) + expect(parentVm.externalValueNormalize).toEqual(7) + expect(parentVm.selection).toEqual(7) + expect(parentVm.child.selectionString).toEqual('7') + expect(parentVm.child.value).toEqual(7) + + + }); }); diff --git a/src/components/GList/listSelectFactory.js b/src/components/GList/listSelectFactory.js index b062bf61..6f28d795 100644 --- a/src/components/GList/listSelectFactory.js +++ b/src/components/GList/listSelectFactory.js @@ -1,4 +1,4 @@ -import { computed, ref } from '@vue/composition-api'; +import { computed, ref, watch } from '@vue/composition-api'; import _ from 'lodash'; export function createItemFn(prop) { @@ -41,9 +41,10 @@ export function makeListSelectable2(props, context) { ) const getText = computed(() => createItemFn(props.itemText)) const getValue = computed(() => createItemFn(props.itemValue)) - + const inCombobox = props.component === 'combobox' || props.inCombobox //todo: normalised value: map value to an item in list if it existed const normalisedValue = computed(() => { + const _normalise = function (value) { if (listType.value === 'primitive') return normalisedList.value.find(item => item === value) else if ((listType.value === 'objectReturnObject' && typeof value === 'object') || typeof value === 'object') return normalisedList.value.find(item => @@ -55,7 +56,7 @@ export function makeListSelectable2(props, context) { //todo: combobox case function normalise(value) { - if (!props.freeItemAllow) return _normalise(value) + if (!inCombobox) return _normalise(value) else { let _normalisedVal = _normalise(value) if (_normalisedVal) return _normalisedVal @@ -67,11 +68,12 @@ export function makeListSelectable2(props, context) { if (!props.multiple) res = props.value ? normalise(props.value) : undefined else res = props.value ? props.value.map(normalise) : [] context.emit('update:externalNormalisedValue', res); + context.emit('update:selectedValue', res); return res }) function unNormalise(item) { - if (listType.value !== 'objectArrayReturnValue') { + if (listType.value !== 'objectWithValueOrText' || typeof item !== 'object') { return item } return getValue.value(item); @@ -80,11 +82,11 @@ export function makeListSelectable2(props, context) { //todo: toggle function : toggle item into props.value const toggleItem = (item) => { if (props.multiple) { - if (listType.value !== 'objectWithValueOrText') updateMultiple(item); + if (listType.value !== 'objectWithValueOrText' || typeof item !== 'object') updateMultiple(item); else if (getValue.value(item)) updateMultiple(getValue.value(item)) else if (getText.value(item)) updateMultiple(getText.value(item)) } else { - if (listType.value !== 'objectWithValueOrText') updateSingle(item); + if (listType.value !== 'objectWithValueOrText' || typeof item !== 'object') updateSingle(item); else if (getValue.value(item)) updateSingle(getValue.value(item)) else if (getText.value(item)) updateSingle(getText.value(item)) } @@ -98,22 +100,22 @@ export function makeListSelectable2(props, context) { const updateMultiple = (item) => { let _normalisedVal - if (listType.value !== 'objectWithValueOrText') _normalisedVal = [...normalisedValue.value] + if (listType.value !== 'objectWithValueOrText' || inCombobox ) _normalisedVal = [...normalisedValue.value] else _normalisedVal = normalisedValue.value.map(item => getValue.value(item) || getText.value(item)) if (normalisedValue.value.includes(item)) { if (props.allowDuplicates) { _normalisedVal.push(item) - emitValue(unNormalise(_normalisedVal)) + emitValue(_normalisedVal.map(unNormalise)) } else { - if (normalisedValue.value.length === 1 && props.mandatory) emitValue(unNormalise(normalisedValue.value)) + if (normalisedValue.value.length === 1 && props.mandatory) emitValue(normalisedValue.value.map(unNormalise())) else { _normalisedVal.splice(normalisedValue.value.indexOf(item)) } } } else { _normalisedVal.push(item) - emitValue(unNormalise(_normalisedVal)) + emitValue(_normalisedVal.map(unNormalise)) } }; @@ -139,8 +141,11 @@ export function makeListSelectable2(props, context) { if (props.allowDuplicates) return normalisedList.value return normalisedList.value.filter(item => !normalisedValue.value.some(el => _.isEqual(el, item))) }) + const searchFn = computed(() => { - let searchText = props.searchText + + let searchText = props.searchText || '' + if (_.isEmpty(searchText.trim() || searchText)) return items => items; //todo: search logic return items => { @@ -149,6 +154,7 @@ export function makeListSelectable2(props, context) { return props.filter(getText.value(item), searchText); }); } + searchText= searchText.toString().toLowerCase() const searchStartsWith = items.filter(item => { return getText.value(item).toString().toLowerCase().startsWith(searchText); }); @@ -163,10 +169,16 @@ export function makeListSelectable2(props, context) { const selectableList = computed(() => { return searchFn.value(selectableValues.value) }) + // const selectableList = ref(null) + // watch(() => props.searchText, () => selectableList.value = searchFn.value(selectableValues.value) + // ) + function emitValue(val) { console.log('emit value: ', JSON.stringify(val)); + console.log('input') context.emit('input', val); + } return { diff --git a/src/components/GSelect/GSelect.vue b/src/components/GSelect/GSelect.vue index 69c2531e..412b222e 100644 --- a/src/components/GSelect/GSelect.vue +++ b/src/components/GSelect/GSelect.vue @@ -149,7 +149,7 @@ inMenu: true, selectable: true, value: selectedValue.value, - externalNormalisedValue: selectedValue.value, + //externalNormalisedValue: selectedValue.value, searchText: state.searchText }, on: { diff --git a/src/components/GSelect/NewSelect.vue b/src/components/GSelect/NewSelect.vue new file mode 100644 index 00000000..2b5a9685 --- /dev/null +++ b/src/components/GSelect/NewSelect.vue @@ -0,0 +1,135 @@ + + + diff --git a/src/components/GSelect/__story__/GSelect.stories.js b/src/components/GSelect/__story__/GSelect.stories.js index 3c6e6dd4..9e047f70 100644 --- a/src/components/GSelect/__story__/GSelect.stories.js +++ b/src/components/GSelect/__story__/GSelect.stories.js @@ -167,7 +167,7 @@ export const GSelectMultiple = () => ({ ` }) export const GSelectMultipleNotAllowDuplicates = () => ({ - components: {GSelect}, + components: {GSelect, NewSelect}, props: { label: {default: text('Input label', 'Label')}, placeholder: {default: text('Input placeholder', '')}, @@ -192,7 +192,7 @@ export const GSelectMultipleNotAllowDuplicates = () => ({ template: `
{{selected}} - ({ multiple :allow-duplicates="allowDuplicates" v-model="selected"> - +
` }) export const GSelectSearchableSingleSelect = () => ({ - components: {GSelect}, + components: {GSelect, NewSelect}, props: { label: {default: text('Input label', 'Label')}, placeholder: {default: text('Input placeholder', '')}, @@ -232,7 +232,7 @@ export const GSelectSearchableSingleSelect = () => ({ } }, template: ` -
({ :clearable="clearable" v-model="selected" searchable> -
`, +`, }) export const GSelectSearchableMultipleSelect = () => ({ components: {GSelect}, @@ -438,6 +438,7 @@ import GListItem from "../../GList/GListItem"; import {GListItemText, GListItemContent, GListItemSubText} from "../../GList/GListFunctionalComponent"; import GDivider from "../../GLayout/GDivider"; import GSelect from "../GSelect"; +import NewSelect from '../NewSelect'; describe('test', function () { it('should', function () { From 1def8cdd5e21db166414e03f4cc4c7637a137be4 Mon Sep 17 00:00:00 2001 From: Pay Duyen Date: Mon, 30 Dec 2019 17:05:48 +0700 Subject: [PATCH 05/18] Fix bugs --- .../GAutocomplete/GAutocomplete.vue | 247 ++----------- .../GAutocomplete/NewAutocomplete.vue | 151 -------- .../__story__/GAutocomplete.stories.js | 16 +- src/components/GCombobox/GCombobox.vue | 329 ++++------------- src/components/GCombobox/NewCombobox.vue | 151 -------- .../GCombobox/SelectableComponent.vue | 60 +--- .../GCombobox/__story__/GCombobox.stories.js | 31 +- src/components/GList/GList.vue | 335 ++++++++---------- src/components/GList/NewList.vue | 277 --------------- .../GList/__story__/GList.stories.js | 40 +-- src/components/GList/listSelectFactory.js | 26 +- src/components/GSelect/GSelect.vue | 274 +++----------- src/components/GSelect/NewSelect.vue | 135 ------- .../GSelect/__story__/GSelect.stories.js | 45 +-- 14 files changed, 374 insertions(+), 1743 deletions(-) delete mode 100644 src/components/GAutocomplete/NewAutocomplete.vue delete mode 100644 src/components/GCombobox/NewCombobox.vue delete mode 100644 src/components/GList/NewList.vue delete mode 100644 src/components/GSelect/NewSelect.vue diff --git a/src/components/GAutocomplete/GAutocomplete.vue b/src/components/GAutocomplete/GAutocomplete.vue index e7faa5cc..f2df6e41 100644 --- a/src/components/GAutocomplete/GAutocomplete.vue +++ b/src/components/GAutocomplete/GAutocomplete.vue @@ -1,20 +1,10 @@ + - diff --git a/src/components/GAutocomplete/__story__/GAutocomplete.stories.js b/src/components/GAutocomplete/__story__/GAutocomplete.stories.js index 760f17eb..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 { @@ -8,7 +11,7 @@ export default { } export const GAutocompleteSingleSelect = () => ({ - components: {GAutocomplete, GSelect, NewAutocomplete}, + components: {GAutocomplete, GSelect}, props: { label: {default: text('Input label', 'Label')}, placeholder: {default: text('Input placeholder', '')}, @@ -77,7 +80,7 @@ export const GAutocompleteSingleSelect = () => ({ > - ({
{{'filter: '+activeFilter}}
`, }) -// testing -import Vue from 'vue/dist/vue.common.js' -import GAutocomplete from "../GAutocomplete"; -import GSelect from "../../GSelect/GSelect"; -import NewAutocomplete from '../NewAutocomplete'; describe('test', function () { it('should', function () { diff --git a/src/components/GCombobox/GCombobox.vue b/src/components/GCombobox/GCombobox.vue index 1029bf14..1f44eb27 100644 --- a/src/components/GCombobox/GCombobox.vue +++ b/src/components/GCombobox/GCombobox.vue @@ -1,23 +1,10 @@ + - diff --git a/src/components/GCombobox/NewCombobox.vue b/src/components/GCombobox/NewCombobox.vue deleted file mode 100644 index cba1cf48..00000000 --- a/src/components/GCombobox/NewCombobox.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - diff --git a/src/components/GCombobox/SelectableComponent.vue b/src/components/GCombobox/SelectableComponent.vue index 95b956d2..9e5295b2 100644 --- a/src/components/GCombobox/SelectableComponent.vue +++ b/src/components/GCombobox/SelectableComponent.vue @@ -1,11 +1,10 @@ - - diff --git a/src/components/GList/NewList.vue b/src/components/GList/NewList.vue deleted file mode 100644 index 05c5579e..00000000 --- a/src/components/GList/NewList.vue +++ /dev/null @@ -1,277 +0,0 @@ - - diff --git a/src/components/GList/__story__/GList.stories.js b/src/components/GList/__story__/GList.stories.js index 5e32bab2..3925a734 100644 --- a/src/components/GList/__story__/GList.stories.js +++ b/src/components/GList/__story__/GList.stories.js @@ -1,27 +1,31 @@ import { boolean, number, text, withKnobs } from '@storybook/addon-knobs'; -import { action } from '@storybook/addon-actions'; import GList from '../GList'; import GListItem from '../GListItem'; import GDivider from '../../GLayout/GDivider.vue'; import { - GListItemIcon, - GListItemAvatar, + GListHeader, GListItemAction, + GListItemAvatar, + GListItemContent, + GListItemIcon, GListItemImage, GListItemImageBig, - GListItemContent, - GListItemText, GListItemSubText, - GListHeader + GListItemText } from '../GListFunctionalComponent' -import NewList from '../NewList'; +import Vue from 'vue/dist/vue.common.js' +import GContainer from '../../GLayout/GContainer'; +import GRow from '../../GLayout/GRow'; +import GCol from '../../GLayout/GCol'; +import GIcon from '../../GIcon/GIcon'; +import GBtn from '../../GBtn/GBtn'; export default { title: 'GList', decorators: [withKnobs], }; export const gListPlayGround = () => ({ - components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader, NewList }, + components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader}, data() { return { items: [ @@ -54,7 +58,7 @@ export const gListPlayGround = () => ({ }, template: ` - ({ `, }) export const gListSingleSelectPlayGround = () => ({ - components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader, NewList }, + components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader }, data() { return { items: [ @@ -105,7 +109,7 @@ export const gListSingleSelectPlayGround = () => ({ template: `
{{testValue}} - ({ :itemText="itemText" :returnObject="returnObject" :activeClass="activeClass"> - +
`, }) export const gListMultiSelectPlayGround = () => ({ - components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader, NewList }, + components: { GDivider, GListItem, GList, GListItemIcon, GListItemAvatar, GListItemAction, GListItemImage, GListItemImageBig, GListItemContent, GListItemText, GListItemSubText, GListHeader }, data() { return { items: [ @@ -166,7 +170,7 @@ export const gListMultiSelectPlayGround = () => ({ template: `
{{testValue}} - ({ itemText="text" :returnObject="returnObject" :activeClass="activeClass"> - +
`, }) export const gListInset = () => ({ @@ -838,12 +842,6 @@ export const gListNumberItems = () => ({ `, }) -import Vue from 'vue/dist/vue.common.js' -import GContainer from '../../GLayout/GContainer'; -import GRow from '../../GLayout/GRow'; -import GCol from '../../GLayout/GCol'; -import GIcon from '../../GIcon/GIcon'; -import GBtn from '../../GBtn/GBtn'; describe('GList', function () { diff --git a/src/components/GList/listSelectFactory.js b/src/components/GList/listSelectFactory.js index 6f28d795..c7f02407 100644 --- a/src/components/GList/listSelectFactory.js +++ b/src/components/GList/listSelectFactory.js @@ -1,4 +1,4 @@ -import { computed, ref, watch } from '@vue/composition-api'; +import { computed } from '@vue/composition-api'; import _ from 'lodash'; export function createItemFn(prop) { @@ -53,8 +53,6 @@ export function makeListSelectable2(props, context) { return normalisedList.value.find(item => getValue.value(item) === value) || normalisedList.value.find(item => getText.value(item) === value) } } - -//todo: combobox case function normalise(value) { if (!inCombobox) return _normalise(value) else { @@ -65,7 +63,7 @@ export function makeListSelectable2(props, context) { } let res - if (!props.multiple) res = props.value ? normalise(props.value) : undefined + if (!props.multiple) res = (props.value || props.value === 0) ? normalise(props.value) : undefined else res = props.value ? props.value.map(normalise) : [] context.emit('update:externalNormalisedValue', res); context.emit('update:selectedValue', res); @@ -79,15 +77,15 @@ export function makeListSelectable2(props, context) { return getValue.value(item); } - //todo: toggle function : toggle item into props.value + //todo: toggle function : toggle item emit value into props.value const toggleItem = (item) => { if (props.multiple) { if (listType.value !== 'objectWithValueOrText' || typeof item !== 'object') updateMultiple(item); - else if (getValue.value(item)) updateMultiple(getValue.value(item)) + else if (getValue.value(item) || getValue.value(item) === 0) updateMultiple(getValue.value(item)) else if (getText.value(item)) updateMultiple(getText.value(item)) } else { if (listType.value !== 'objectWithValueOrText' || typeof item !== 'object') updateSingle(item); - else if (getValue.value(item)) updateSingle(getValue.value(item)) + else if (getValue.value(item) || getValue.value(item) === 0) updateSingle(getValue.value(item)) else if (getText.value(item)) updateSingle(getText.value(item)) } }; @@ -100,7 +98,7 @@ export function makeListSelectable2(props, context) { const updateMultiple = (item) => { let _normalisedVal - if (listType.value !== 'objectWithValueOrText' || inCombobox ) _normalisedVal = [...normalisedValue.value] + if (listType.value !== 'objectWithValueOrText' || inCombobox) _normalisedVal = [...normalisedValue.value] else _normalisedVal = normalisedValue.value.map(item => getValue.value(item) || getText.value(item)) if (normalisedValue.value.includes(item)) { @@ -154,7 +152,7 @@ export function makeListSelectable2(props, context) { return props.filter(getText.value(item), searchText); }); } - searchText= searchText.toString().toLowerCase() + searchText = searchText.toString().toLowerCase() const searchStartsWith = items.filter(item => { return getText.value(item).toString().toLowerCase().startsWith(searchText); }); @@ -169,10 +167,6 @@ export function makeListSelectable2(props, context) { const selectableList = computed(() => { return searchFn.value(selectableValues.value) }) - // const selectableList = ref(null) - // watch(() => props.searchText, () => selectableList.value = searchFn.value(selectableValues.value) - // ) - function emitValue(val) { console.log('emit value: ', JSON.stringify(val)); @@ -204,7 +198,7 @@ export function getSelection2(props, context, selectedValue, listType, getText, else if (getText.value(item) || getValue.value(item)) return { text: getText.value(item) || '', value: getValue.value(item) || '' } return '' } - const list = selectedValue.value + const list = selectedValue.value || [] return list.map(item => { if (listType.value === 'primitive') return item else if (getText.value(item) || getValue.value(item)) return { text: getText.value(item) || '', value: getValue.value(item) || '' } @@ -220,13 +214,13 @@ export function getSelection3(props, selectedValue, listType, getText, getValue) let _item = props.items.find(el => getValue.value(el) ? getValue.value(el) === item : getText.value(el) === item) if (!item && item !== 0) return '' if (listType.value === 'primitive') return item - return { text: getText.value(_item || item) || '', value: getValue.value(_item || item) || '' } + return { text: getText.value(_item || item) || '', value: (getValue.value(_item || item) || getValue.value(_item || item) === 0) ? getValue.value(_item || item) : '' } } const list = selectedValue.value || [] return list.map(item => { let _item = props.items.find(el => getValue.value(el) ? getValue.value(el) === item : getText.value(el) === item) if (listType.value === 'primitive') return item - return { text: getText.value(_item || item) || '', value: getValue.value(_item || item) || '' } + return { text: getText.value(_item || item) || '', value: (getValue.value(_item || item) || getValue.value(_item || item) === 0) ? getValue.value(_item || item) : '' } }) }) diff --git a/src/components/GSelect/GSelect.vue b/src/components/GSelect/GSelect.vue index 412b222e..04f1f625 100644 --- a/src/components/GSelect/GSelect.vue +++ b/src/components/GSelect/GSelect.vue @@ -1,21 +1,10 @@ + diff --git a/src/components/GSelect/NewSelect.vue b/src/components/GSelect/NewSelect.vue deleted file mode 100644 index 2b5a9685..00000000 --- a/src/components/GSelect/NewSelect.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - diff --git a/src/components/GSelect/__story__/GSelect.stories.js b/src/components/GSelect/__story__/GSelect.stories.js index 9e047f70..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 { @@ -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', 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: ` @@ -167,7 +171,7 @@ export const GSelectMultiple = () => ({ ` }) export const GSelectMultipleNotAllowDuplicates = () => ({ - components: {GSelect, NewSelect}, + components: {GSelect}, props: { label: {default: text('Input label', 'Label')}, placeholder: {default: text('Input placeholder', '')}, @@ -192,7 +196,7 @@ export const GSelectMultipleNotAllowDuplicates = () => ({ template: `
{{selected}} - ({ multiple :allow-duplicates="allowDuplicates" v-model="selected"> - +
` }) export const GSelectSearchableSingleSelect = () => ({ - components: {GSelect, NewSelect}, + components: {GSelect}, props: { label: {default: text('Input label', 'Label')}, placeholder: {default: text('Input placeholder', '')}, @@ -232,7 +236,7 @@ export const GSelectSearchableSingleSelect = () => ({ } }, template: ` -
({ :clearable="clearable" v-model="selected" searchable> -
`, +`, }) export const GSelectSearchableMultipleSelect = () => ({ components: {GSelect}, @@ -429,17 +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"; -import NewSelect from '../NewSelect'; - describe('test', function () { it('should', function () { const vm = new Vue(test1()).$mount(); From 3370e0b9acc39bc75557da67b88895bdf660db5c Mon Sep 17 00:00:00 2001 From: Pay Duyen Date: Mon, 30 Dec 2019 18:00:01 +0700 Subject: [PATCH 06/18] Fix bugs --- .../GAutocomplete/GAutocompleteFactory.js | 60 ----------------- .../GCombobox/SelectableComponent.vue | 14 +--- .../GList/__tests__/listSelectTest2.test.js | 67 ++++++++----------- src/components/GList/listSelectFactory.js | 26 ++++++- 4 files changed, 54 insertions(+), 113 deletions(-) diff --git a/src/components/GAutocomplete/GAutocompleteFactory.js b/src/components/GAutocomplete/GAutocompleteFactory.js index e9f109af..8204c6c6 100644 --- a/src/components/GAutocomplete/GAutocompleteFactory.js +++ b/src/components/GAutocomplete/GAutocompleteFactory.js @@ -1,5 +1,4 @@ import { keyCodes } from '../../utils/helpers'; -import { ref } from '@vue/composition-api' export function getInputEventHandlers(props, context, state, selections, selectedItem, isFocused, toggleItem, showOptions) { const isInputDisplay = !props.multiple && !(props.chips || props.smallChips || props.deletableChips) @@ -91,64 +90,5 @@ export function setSearch(props, context, selections, state) { }) } -//shared render functions -// export function genMenu(props, showOptions, isFocused) { -// const nudgeBottom = computed(() => !!props.hint ? '22px' : '2px') -// return props.genActivator, -// default: () => props.genMenuContent -// }, -// on: { -// input: (e) => isFocused.value ? showOptions.value = true : showOptions.value = e, -// } -// }} -// /> -// } -// -// export function genComponent(props, showOptions) { -// let activeClass = props.component + '__active' -// return
-// {genMenu(showOptions)} -//
-// } -// -// export function genList(props, context, showOptions, selectedValue, state) { -// return showOptions.value = props.multiple, -// input: e => { -// selectedValue.value = e -// context.emit('input', e) -// }, -// }, -// scopedSlots: { -// content: () => context.slots.item && context.slots.item() -// } -// }} -// ref="list" -// /> -// } diff --git a/src/components/GCombobox/SelectableComponent.vue b/src/components/GCombobox/SelectableComponent.vue index 9e5295b2..3be87faf 100644 --- a/src/components/GCombobox/SelectableComponent.vue +++ b/src/components/GCombobox/SelectableComponent.vue @@ -1,5 +1,5 @@ - From 8f2028d9f3a2b55c7a2d61ab34f67e3a691be8a1 Mon Sep 17 00:00:00 2001 From: Pay Duyen Date: Mon, 30 Dec 2019 18:04:44 +0700 Subject: [PATCH 08/18] Fix bugs --- src/components/GList/listSelectFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/GList/listSelectFactory.js b/src/components/GList/listSelectFactory.js index 526c350e..91faf404 100644 --- a/src/components/GList/listSelectFactory.js +++ b/src/components/GList/listSelectFactory.js @@ -189,7 +189,7 @@ export function makeListSelectable2(props, context) { } function isTruthy(value){ - return value === 0 || value === true || value !== undefined|| value !== '' || value !==null + return value === 0 || !!value } export function getSelection2(props, context, selectedValue, listType, getText, getValue) { return computed(() => { From d7c35f9345f49297e39b995a64a994f1083c2859 Mon Sep 17 00:00:00 2001 From: Pay Duyen Date: Mon, 30 Dec 2019 18:06:24 +0700 Subject: [PATCH 09/18] Fix bugs --- src/components/GList/listSelectFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/GList/listSelectFactory.js b/src/components/GList/listSelectFactory.js index 91faf404..652408d2 100644 --- a/src/components/GList/listSelectFactory.js +++ b/src/components/GList/listSelectFactory.js @@ -203,7 +203,7 @@ export function getSelection2(props, context, selectedValue, listType, getText, const list = selectedValue.value || [] return list.map(item => { if (listType.value === 'primitive') return item - else if (getText.value(item) || getValue.value(item)) return { text: getText.value(item) || '', value: (getValue.value(item) || getValue.value(item) === 0) ? getValue.value(item) : '' } + else if (isTruthy(getText.value(item)) || isTruthy(getValue.value(item)) ) return { text: isTruthy(getText.value(item)) ? getText.value(item) : '', value: isTruthy(getValue.value(item)) ? getValue.value(item) : '' } return '' }) }) From 3d1cfe1e38a5d5db33d232aeaa3b434faa0ea369 Mon Sep 17 00:00:00 2001 From: Pay Duyen Date: Thu, 2 Jan 2020 10:33:57 +0700 Subject: [PATCH 10/18] change combobox getSelect --- .../GCombobox/SelectableComponent.vue | 32 +++++++++---------- src/components/GInput/GTextField.vue | 6 ++-- .../GList/__tests__/listSelectTest2.test.js | 18 ----------- src/components/GList/listSelectFactory.js | 3 ++ 4 files changed, 21 insertions(+), 38 deletions(-) diff --git a/src/components/GCombobox/SelectableComponent.vue b/src/components/GCombobox/SelectableComponent.vue index 3be87faf..50d6f0ce 100644 --- a/src/components/GCombobox/SelectableComponent.vue +++ b/src/components/GCombobox/SelectableComponent.vue @@ -1,5 +1,5 @@