diff --git a/.eslintrc.json b/.eslintrc.json index b0798e5..fb69913 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,7 @@ { "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint", "prettier", "jest", "unused-imports"], - "extends": ["@open-wc", "prettier"], + "extends": ["@open-wc", "prettier", "eslint:recommended"], "rules": { "@typescript-eslint/ban-ts-comment": "warn", "@typescript-eslint/ban-types": "warn", diff --git a/custom-elements.json b/custom-elements.json new file mode 100644 index 0000000..2c05d3a --- /dev/null +++ b/custom-elements.json @@ -0,0 +1,180 @@ +{ + "schemaVersion": "1.0.0", + "readme": "", + "modules": [ + { + "kind": "javascript-module", + "path": "src/DominoClock.ts", + "declarations": [ + { + "kind": "class", + "description": "", + "name": "DominoClock", + "members": [ + { + "kind": "field", + "name": "faces", + "type": { + "text": "HTMLCollection" + } + }, + { + "kind": "field", + "name": "timer", + "type": { + "text": "number" + }, + "default": "0" + }, + { + "kind": "method", + "name": "paint" + } + ], + "superclass": { + "name": "LitElement", + "package": "lit" + }, + "customElement": true + } + ], + "exports": [ + { + "kind": "js", + "name": "DominoClock", + "declaration": { + "name": "DominoClock", + "module": "src/DominoClock.ts" + } + }, + { + "kind": "js", + "name": "default", + "declaration": { + "name": "DominoClock", + "module": "src/DominoClock.ts" + } + } + ] + }, + { + "kind": "javascript-module", + "path": "src/DominoFace.ts", + "declarations": [ + { + "kind": "class", + "description": "", + "name": "DominoClockface", + "members": [ + { + "kind": "field", + "name": "name", + "type": { + "text": "string" + }, + "default": "\"hour\"" + }, + { + "kind": "field", + "name": "time", + "type": { + "text": "string" + }, + "default": "\"12\"" + }, + { + "kind": "field", + "name": "dots", + "type": { + "text": "HTMLCollection" + } + }, + { + "kind": "method", + "name": "calculateDots" + } + ], + "superclass": { + "name": "LitElement", + "package": "lit" + }, + "customElement": true + } + ], + "exports": [ + { + "kind": "js", + "name": "DominoClockface", + "declaration": { + "name": "DominoClockface", + "module": "src/DominoFace.ts" + } + }, + { + "kind": "js", + "name": "default", + "declaration": { + "name": "DominoClockface", + "module": "src/DominoFace.ts" + } + } + ] + }, + { + "kind": "javascript-module", + "path": "src/index.ts", + "declarations": [], + "exports": [ + { + "kind": "js", + "name": "DominoClock", + "declaration": { + "name": "DominoClock", + "module": "src/index.ts" + } + }, + { + "kind": "js", + "name": "default", + "declaration": { + "name": "DominoClock", + "module": "src/index.ts" + } + } + ] + }, + { + "kind": "javascript-module", + "path": "build/assets/index.c09ad8c7.js", + "declarations": [ + { + "kind": "variable", + "name": "n3" + }, + { + "kind": "variable", + "name": "e3", + "default": "t2" + } + ], + "exports": [ + { + "kind": "custom-element-definition", + "name": "e3", + "declaration": { + "name": "n3", + "module": "build/assets/index.c09ad8c7.js" + } + }, + { + "kind": "custom-element-definition", + "name": "e3", + "declaration": { + "name": "n4", + "module": "build/assets/index.c09ad8c7.js" + } + } + ] + } + ] +} diff --git a/package-lock.json b/package-lock.json index 6834867..0eda8dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "lit": "^2.0.2" }, "devDependencies": { + "@custom-elements-manifest/analyzer": "^0.4.17", "@open-wc/eslint-config": "^9.2.1", "@types/jest": "^27.0.2", "@typescript-eslint/eslint-plugin": "^5.48.0", @@ -557,6 +558,26 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@custom-elements-manifest/analyzer": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.4.17.tgz", + "integrity": "sha512-4eFORsv7W6cH0s7iSEC1urU9ZnDGCTlCh6AvzzkIWhPhFwCI6PyF+xWXj0mxme6UYxpC6lite/cGj42QV/q3Cw==", + "dev": true, + "dependencies": { + "@web/config-loader": "^0.1.3", + "chokidar": "^3.5.2", + "command-line-args": "^5.1.2", + "comment-parser": "^1.2.0", + "custom-elements-manifest": "^1.0.0", + "debounce": "^1.2.1", + "globby": "^11.0.4", + "typescript": "^4.3.2" + }, + "bin": { + "cem": "index.js", + "custom-elements-manifest": "index.js" + } + }, "node_modules/@esbuild/linux-loong64": { "version": "0.14.54", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", @@ -1986,6 +2007,51 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@web/config-loader": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.1.3.tgz", + "integrity": "sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ==", + "dev": true, + "dependencies": { + "semver": "^7.3.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@web/config-loader/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@web/config-loader/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@web/config-loader/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -2136,6 +2202,15 @@ "deep-equal": "^2.0.5" } }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", @@ -2407,6 +2482,15 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2548,6 +2632,45 @@ "node": ">=10" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -2632,6 +2755,30 @@ "node": ">= 0.8" } }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/comment-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", + "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2688,6 +2835,12 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, + "node_modules/custom-elements-manifest": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz", + "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A==", + "dev": true + }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -2702,6 +2855,12 @@ "node": ">=10" } }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4370,6 +4529,18 @@ "node": ">=8" } }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4970,6 +5141,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -7406,6 +7589,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -8086,6 +8275,18 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -8817,6 +9018,15 @@ "node": ">=4.2.0" } }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -9743,6 +9953,22 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@custom-elements-manifest/analyzer": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.4.17.tgz", + "integrity": "sha512-4eFORsv7W6cH0s7iSEC1urU9ZnDGCTlCh6AvzzkIWhPhFwCI6PyF+xWXj0mxme6UYxpC6lite/cGj42QV/q3Cw==", + "dev": true, + "requires": { + "@web/config-loader": "^0.1.3", + "chokidar": "^3.5.2", + "command-line-args": "^5.1.2", + "comment-parser": "^1.2.0", + "custom-elements-manifest": "^1.0.0", + "debounce": "^1.2.1", + "globby": "^11.0.4", + "typescript": "^4.3.2" + } + }, "@esbuild/linux-loong64": { "version": "0.14.54", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", @@ -10824,6 +11050,41 @@ } } }, + "@web/config-loader": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.1.3.tgz", + "integrity": "sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ==", + "dev": true, + "requires": { + "semver": "^7.3.4" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -10937,6 +11198,12 @@ "deep-equal": "^2.0.5" } }, + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + }, "array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", @@ -11138,6 +11405,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -11235,6 +11508,33 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -11300,6 +11600,24 @@ "delayed-stream": "~1.0.0" } }, + "command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "comment-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", + "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -11352,6 +11670,12 @@ } } }, + "custom-elements-manifest": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz", + "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A==", + "dev": true + }, "data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -11363,6 +11687,12 @@ "whatwg-url": "^8.0.0" } }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -12519,6 +12849,15 @@ "to-regex-range": "^5.0.1" } }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "requires": { + "array-back": "^3.0.1" + } + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -12948,6 +13287,15 @@ "has-bigints": "^1.0.1" } }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -14760,6 +15108,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -15249,6 +15603,15 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -15788,6 +16151,12 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", diff --git a/package.json b/package.json index 252b062..3314cee 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,10 @@ "description": "The Domino Clock", "main": "build/index.js", "scripts": { + "analyze": "cem analyze --litelement", "build": "vite build --base='./'", - "lint": "eslint", + "lint": "eslint --ignore-path .gitignore && prettier --check --ignore-path .gitignore", + "fix": "eslint --fix --ignore-path .gitignore && prettier --write --ignore-path .gitignore", "dev": "vite -m development", "test": "jest" }, @@ -15,6 +17,7 @@ "lit": "^2.0.2" }, "devDependencies": { + "@custom-elements-manifest/analyzer": "^0.4.17", "@open-wc/eslint-config": "^9.2.1", "@types/jest": "^27.0.2", "@typescript-eslint/eslint-plugin": "^5.48.0", @@ -32,5 +35,6 @@ "vite-plugin-compression": "^0.3.5", "vite-plugin-ejs": "^1.4.3", "vite-plugin-eslint": "^1.3.0" - } + }, + "customElements": "custom-elements.json" } diff --git a/src/DominoClock.ts b/src/DominoClock.ts index e6bce34..ea25f8a 100644 --- a/src/DominoClock.ts +++ b/src/DominoClock.ts @@ -2,29 +2,35 @@ import { LitElement, css, html } from "lit"; import { customElement, queryAll } from "lit/decorators.js"; import "./DominoFace.ts"; -type Times = number[]; -type Cats = Times; -const MATRIX: Cats[] = [ - [1, 5, 8, 9, 11], - [2, 5, 6, 10, 11], - [3, 6, 7, 9, 11], - [4, 7, 8, 10, 11], -]; - -const tock = (time: number) => [0, 1, 2, 3].map(i => MATRIX[i].includes(time)); +function times() { + const now = new Date(); + const rawHours = now.getHours(); + return { + hour: rawHours > 12 ? rawHours - 12 : rawHours, + minute: Math.floor(now.getUTCMinutes() / 5), + second: Math.floor(now.getUTCSeconds() / 5), + }; +} @customElement("domino-clock") export class DominoClock extends LitElement { - timer: number; + static styles = css` + :host { + --dominoclock-default-direction: row; + --dominoclock-default-face-gap: 0.25rem; + } - hour = [false, false, false, false]; - - minute = [false, false, false, false]; - - second = [false, false, false, false]; + .dominoclock { + display: flex; + flex-direction: var(--dominoclock-direction, var(--dominoclock-default-direction, row)); + gap: var(--dominoclock-face-gap, var(--dominoclock-default-face-gap, 0.25rem)); + } + `; @queryAll("domino-face") faces: HTMLCollection; + timer: number; + constructor() { super(); this.timer = 0; @@ -32,14 +38,12 @@ export class DominoClock extends LitElement { } paint() { - const now = new Date(); - const rawHours = now.getHours(); - this.hour = tock(rawHours > 12 ? rawHours - 12 : rawHours); - this.minute = tock(Math.floor(now.getUTCMinutes() / 5)); - this.second = tock(Math.floor(now.getUTCSeconds() / 5)); + const update = times(); + Array.from(this.faces).forEach(face => { + const name = face.getAttribute("name"); + face.setAttribute("time", `${update[name]}`); + }); this.timer = window.setTimeout(this.paint, 250); - const times = [this.hour, this.minute, this.second]; - Array.from(this.faces).forEach((face, idx) => face.tick(times[idx])); } connectedCallback() { @@ -56,24 +60,12 @@ export class DominoClock extends LitElement { } } - static styles = css` - :host { - --dominoclock-default-direction: row; - --dominoclock-default-face-gap: 0.25rem; - } - - .dominoclock { - display: flex; - flex-direction: var(--dominoclock-direction, var(--dominoclock-default-direction, row)); - gap: var(--dominoclock-face-gap, var(--dominoclock-default-face-gap, 0.25rem)); -D. } - `; - render() { + const update = times(); return html`
- - - + + +
`; } } diff --git a/src/DominoFace.ts b/src/DominoFace.ts index c0d00fa..d56efc1 100644 --- a/src/DominoFace.ts +++ b/src/DominoFace.ts @@ -1,23 +1,23 @@ import { LitElement, css, html } from "lit"; import { customElement, property, queryAll } from "lit/decorators.js"; -type Dots = [boolean, boolean, boolean, boolean]; +type Times = number[]; +type Coordinates = Times; +const MATRIX: Coordinates[] = [ + [1, 5, 8, 9, 11], + [2, 5, 6, 10, 11], + [3, 6, 7, 9, 11], + [4, 7, 8, 10, 11], +]; -function timeChanged(oldvalue: Dots, newvalue: Dots): boolean { - if (!newvalue) { - return true; - } - return !oldvalue.reduce((acc, t, idx) => acc && t === newvalue[idx], true); -} +// An element that takes a single attribute, "time," which is a number between 1 +// and 12; that number is scanned in the Coordinates matrix above to determine +// which of four dots should be illuminated, reflecting 12 patterns that can be +// memorized to represent the time. After rendering, if the attribute changes, +// the active/hidden dots are recalculated. @customElement("domino-face") export class DominoClockface extends LitElement { - @property({ type: Array, hasChanged: timeChanged }) time = [false, false, false, false]; - - @queryAll(".dot") dots: HTMLCollection; - - rendered: boolean = false; - static styles = css` :host { --dominoclock-default-dot-size: 1rem; @@ -63,27 +63,26 @@ export class DominoClockface extends LitElement { } `; - tick(time) { - Array.from(this.dots).forEach((dot, idx) => { - if (time[idx]) { - dot.classList.add("active"); - } else { - dot.classList.remove("active"); - } - }); + @property({ type: String }) name = "hour"; + + @property({ type: String }) time = "12"; + + @queryAll(".dot") dots: HTMLCollection; + + calculateDots() { + const time = parseInt(this.time, 10); + return [0, 1, 2, 3].map(i => MATRIX[i].includes(time)); } render() { + const points = this.calculateDots(); return html`
- ${this.time.map(pos => - pos - ? html` -
- ` - : html` -
- ` + ${points.map( + pos => + html` +
+ ` )}
`;