Updated all NPM versioning and switched to lit-html.
This commit is contained in:
parent
6c9ac44eac
commit
0ba271be28
112
.eslintrc.json
112
.eslintrc.json
|
@ -1,58 +1,58 @@
|
|||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint", "eslint-plugin-import", "prettier"],
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": ["plugin:@typescript-eslint/recommended", "prettier"],
|
||||
"parserOptions": {
|
||||
"project": ["tsconfig.json"],
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"no-await-in-loop": "off",
|
||||
"no-use-before-define": "off",
|
||||
"no-nested-ternary": "off",
|
||||
"@typescript-eslint/no-use-before-define": ["error"],
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"import/extensions": "off",
|
||||
"import/prefer-default-export": "off",
|
||||
"@typescript-eslint/ban-types": "warn",
|
||||
"@typescript-eslint/no-use-before-define": "warn",
|
||||
"arrow-body-style": "warn",
|
||||
"camelcase": "warn",
|
||||
"dot-notation": "warn",
|
||||
"eqeqeq": "warn",
|
||||
"import/first": "warn",
|
||||
"import/newline-after-import": "warn",
|
||||
"import/no-extraneous-dependencies": "warn",
|
||||
"import/order": "warn",
|
||||
"no-else-return": "warn",
|
||||
"no-param-reassign": "warn",
|
||||
"no-return-assign": "warn",
|
||||
"no-sequences": "warn",
|
||||
"no-shadow": "off",
|
||||
"@typescript-eslint/no-shadow": ["warn"],
|
||||
"no-underscore-dangle": "warn",
|
||||
"no-unneeded-ternary": "warn",
|
||||
"object-shorthand": "warn",
|
||||
"prefer-arrow-callback": "warn",
|
||||
"prefer-const": "warn",
|
||||
"prefer-destructuring": "warn",
|
||||
"prefer-template": "warn"
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"node": {
|
||||
"extensions": [".js", ".ts"]
|
||||
},
|
||||
"typescript": {
|
||||
"project": "./tsconfig.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint", "prettier", "jest", "unused-imports"],
|
||||
"extends": ["@open-wc", "prettier"],
|
||||
"rules": {
|
||||
"@typescript-eslint/ban-ts-comment": "warn",
|
||||
"@typescript-eslint/ban-types": "warn",
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/no-shadow": ["warn"],
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-use-before-define": ["error", { "functions": false }],
|
||||
"arrow-body-style": "warn",
|
||||
"camelcase": "off",
|
||||
"default-param-last": "off",
|
||||
"dot-notation": "warn",
|
||||
"eqeqeq": "warn",
|
||||
"import/extensions": "off",
|
||||
"import/first": "warn",
|
||||
"import/newline-after-import": "warn",
|
||||
"import/no-cycle": "warn",
|
||||
"import/no-extraneous-dependencies": "warn",
|
||||
"import/order": "warn",
|
||||
"import/prefer-default-export": "warn",
|
||||
"no-else-return": "warn",
|
||||
"no-nested-ternary": "off",
|
||||
"no-param-reassign": "warn",
|
||||
"no-return-assign": "warn",
|
||||
"no-sequences": "warn",
|
||||
"no-shadow": "off",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-unneeded-ternary": "warn",
|
||||
"no-unused-vars": "off",
|
||||
"no-use-before-define": "off",
|
||||
"object-shorthand": "warn",
|
||||
"one-var": ["error", "never"],
|
||||
"one-var-declaration-per-line": ["error", "initializations"],
|
||||
"prefer-arrow-callback": "warn",
|
||||
"prefer-const": "warn",
|
||||
"prefer-destructuring": "warn",
|
||||
"prefer-template": "warn",
|
||||
"sort-imports": [
|
||||
"error",
|
||||
{
|
||||
"ignoreDeclarationSort": true
|
||||
}
|
||||
],
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
14
.prettierrc
14
.prettierrc
|
@ -1,8 +1,10 @@
|
|||
{
|
||||
"trailingComma": "es5",
|
||||
"printWidth": 110,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": false
|
||||
"useTabs": false,
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "all",
|
||||
"bracketSameLine": false,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
|
12
index.html
12
index.html
|
@ -15,7 +15,8 @@
|
|||
font-family: "Mulish", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.36;
|
||||
letter-spacing: 0.012em;
|
||||
letter-spacing: 0.012em;
|
||||
padding: 1rem;
|
||||
}
|
||||
p {
|
||||
color: #282828;
|
||||
|
@ -32,10 +33,11 @@
|
|||
algorithm of the watch.
|
||||
</p>
|
||||
<p>
|
||||
25 years later, I found the source code buried somewhere in an old CD. I decided to try an
|
||||
re-implement the logic in Javascript, and to experiment with a hand-written
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components">Web Component</a>. This is
|
||||
the result.
|
||||
25 years later, I found the source code buried somewhere in an old
|
||||
CD. I decided to try an re-implement the logic in Javascript, and to
|
||||
experiment with a
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components">Web Component</a>,
|
||||
using the <a href="https://lit.dev">lit-html library</a>. This is the result.
|
||||
</p>
|
||||
<p>
|
||||
It might seem a bit silly to have implemented the seconds face when the minutes face has a
|
||||
|
|
File diff suppressed because it is too large
Load Diff
65
package.json
65
package.json
|
@ -1,33 +1,36 @@
|
|||
{
|
||||
"name": "DominoClock",
|
||||
"version": "1.0.0",
|
||||
"description": "The Domino Clock",
|
||||
"main": "build/index.js",
|
||||
"scripts": {
|
||||
"build": "vite build --base='./'",
|
||||
"lint": "eslint",
|
||||
"dev": "vite -m development",
|
||||
"test": "jest"
|
||||
},
|
||||
"author": "Elf M. Sternberg <elf.sternberg@gmail.com>",
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"eslint": "^8.2.0",
|
||||
"eslint-config-airbnb": "^19.0.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-import-resolver-typescript": "^2.5.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"jest": "^27.3.1",
|
||||
"prettier": "^2.4.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^4.4.4",
|
||||
"vite": "^2.6.14",
|
||||
"vite-plugin-compression": "^0.3.5",
|
||||
"vite-plugin-ejs": "^1.4.3",
|
||||
"vite-plugin-eslint": "^1.3.0"
|
||||
}
|
||||
"name": "DominoClock",
|
||||
"version": "1.0.0",
|
||||
"description": "The Domino Clock",
|
||||
"main": "build/index.js",
|
||||
"scripts": {
|
||||
"build": "vite build --base='./'",
|
||||
"lint": "eslint",
|
||||
"dev": "vite -m development",
|
||||
"test": "jest"
|
||||
},
|
||||
"author": "Elf M. Sternberg <elf.sternberg@gmail.com>",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"lit": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@open-wc/eslint-config": "^9.2.1",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
||||
"@typescript-eslint/parser": "^5.48.0",
|
||||
"eslint": "^8.3.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-jest": "^27.2.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"jest": "^27.3.1",
|
||||
"prettier": "^2.4.1",
|
||||
"typescript": "^4.5.2",
|
||||
"vite": "^2.6.14",
|
||||
"vite-plugin-compression": "^0.3.5",
|
||||
"vite-plugin-ejs": "^1.4.3",
|
||||
"vite-plugin-eslint": "^1.3.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } 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));
|
||||
|
||||
@customElement("domino-clock")
|
||||
export class DominoClock extends LitElement {
|
||||
timer: number;
|
||||
|
||||
@state() hour = [false, false, false, false];
|
||||
|
||||
@state() minute = [false, false, false, false];
|
||||
|
||||
@state() second = [false, false, false, false];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.timer = 0;
|
||||
this.paint = this.paint.bind(this);
|
||||
}
|
||||
|
||||
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));
|
||||
this.timer = window.setTimeout(this.paint, 250);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (super.connectedCallback) {
|
||||
super.connectedCallback();
|
||||
}
|
||||
this.timer = window.setTimeout(this.paint, 250);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
window.clearTimeout(this.timer);
|
||||
if (super.disconnectedCallback) {
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
`;
|
||||
|
||||
render() {
|
||||
return html` <div class="dominoclock">
|
||||
<domino-face .time=${this.hour}></domino-face>
|
||||
<domino-face .time=${this.minute}></domino-face>
|
||||
<domino-face .time=${this.second}></domino-face>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default DominoClock;
|
|
@ -0,0 +1,71 @@
|
|||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
type Dots = [boolean, boolean, boolean, boolean];
|
||||
|
||||
function timeChanged(oldvalue: Dots, newvalue: Dots): boolean {
|
||||
if (!newvalue) {
|
||||
return true;
|
||||
}
|
||||
return !oldvalue.reduce((acc, t, idx) => acc && t === newvalue[idx], true);
|
||||
}
|
||||
|
||||
@customElement("domino-face")
|
||||
export class DominoClockface extends LitElement {
|
||||
@property({ type: Array, hasChanged: timeChanged }) time = [false, false, false, false];
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
--dominoclock-default-dot-size: 1rem;
|
||||
--dominoclock-default-dot-color: #2f4f4f;
|
||||
--dominoclock-default-face-size: 5rem;
|
||||
--dominoclock-default-background-color: #daaf20;
|
||||
--dominoclock-default-border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.face {
|
||||
position: relative;
|
||||
width: var(--dominoclock-face-size, var(--dominoclock-default-face-size, 5rem));
|
||||
height: var(--dominoclock-face-size, var(--dominoclock-default-face-size, 5rem));
|
||||
background-color: var(
|
||||
--dominoclock-background-color,
|
||||
var(--dominoclock-default-background-color, #daaf20)
|
||||
);
|
||||
border: 1px solid #282828;
|
||||
border-radius: var(--dominoclock-border-radius, var(--dominoclock-default-border-radius, 0.5rem));
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
place-items: center center;
|
||||
}
|
||||
|
||||
.dot > div {
|
||||
transition: opacity 0.3s ease;
|
||||
width: var(--dominoclock-date-size, var(--dominoclock-default-date-size, 1rem));
|
||||
height: var(--dominoclock-date-size, var(--dominoclock-default-date-size, 1rem));
|
||||
background-color: var(--dominoclock-dot-color, var(--dominoclock-default-dot-color, #2f4f4f));
|
||||
border-radius: calc(var(--dominoclock-dot-size, var(--dominoclock-default-dot-size, 1rem)) / 2);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.dot.active > div {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
render() {
|
||||
return html`<div class="face">
|
||||
${this.time.map(pos =>
|
||||
pos ? html`<div class="dot active"><div></div></div>` : html`<div class="dot"><div></div></div>`
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default DominoClockface;
|
144
src/index.ts
144
src/index.ts
|
@ -1,142 +1,4 @@
|
|||
type Times = number[];
|
||||
type Cats = [string, Times];
|
||||
const MATRIX: Cats[] = [
|
||||
["o0", [1, 5, 8, 9, 11]],
|
||||
["o1", [2, 5, 6, 10, 11]],
|
||||
["o2", [3, 6, 7, 9, 11]],
|
||||
["o3", [4, 7, 8, 10, 11]],
|
||||
];
|
||||
import { DominoClock } from "./DominoClock.ts";
|
||||
|
||||
const TEMPLATE = `
|
||||
<style>
|
||||
.dominoclock {
|
||||
display: flex;
|
||||
flex-direction: var(--dominoclock-direction, row);
|
||||
}
|
||||
.face {
|
||||
position: relative;
|
||||
width: var(--dominoclock-size, 5rem);
|
||||
height: var(--dominoclock-size, 5rem);
|
||||
background-color: var(--dominoclock-background, #daaf20);
|
||||
border: 1px solid #282828;
|
||||
border-radius: var(--domino-clock-borderradius, 0.5rem);
|
||||
|
||||
}
|
||||
|
||||
.face:not(:last-child) {
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
.dot {
|
||||
position: absolute;
|
||||
width: var(--dominoclock-dot-size, 1rem);
|
||||
height: var(--dominoclock-dot-size, 1rem);
|
||||
background-color: var(--dominoclock-dot-color, #2f4f4f);
|
||||
transition: opacity 0.3s ease;
|
||||
border-radius: calc(var(--dominoclock-dot-size, 1rem) / 2);
|
||||
opacity: 0;
|
||||
}
|
||||
.o0 {
|
||||
top: var(--dominoclock-dot-size, 1rem);
|
||||
left: var(--dominoclock-dot-size, 1rem);
|
||||
}
|
||||
.o1 {
|
||||
top: var(--dominoclock-dot-size, 1rem);
|
||||
left: calc(3 * var(--dominoclock-dot-size, 1rem));
|
||||
}
|
||||
.o2 {
|
||||
top: calc(3 * var(--dominoclock-dot-size, 1rem));
|
||||
left: calc(3 * var(--dominoclock-dot-size, 1rem));
|
||||
}
|
||||
.o3 {
|
||||
top: calc(3 * var(--dominoclock-dot-size, 1rem));
|
||||
left: var(--dominoclock-dot-size, 1rem);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="dominoclock">
|
||||
<div class="face" id="hours">
|
||||
<div class="dot o0" ></div>
|
||||
<div class="dot o1" ></div>
|
||||
<div class="dot o2" ></div>
|
||||
<div class="dot o3" ></div>
|
||||
</div>
|
||||
<div class="face" id="minutes">
|
||||
<div class="dot o0" ></div>
|
||||
<div class="dot o1" ></div>
|
||||
<div class="dot o2" ></div>
|
||||
<div class="dot o3" ></div>
|
||||
</div>
|
||||
<div class="face" id="seconds">
|
||||
<div class="dot o0" ></div>
|
||||
<div class="dot o1" ></div>
|
||||
<div class="dot o2" ></div>
|
||||
<div class="dot o3" ></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
type Face = "hours" | "minutes" | "seconds";
|
||||
|
||||
const isFace = (v: unknown): v is Face => {
|
||||
if (typeof v === "string" && ["hours", "minutes", "seconds"].includes(v)) {
|
||||
return true;
|
||||
}
|
||||
throw new Error(`Expected a Face, got ${v}`);
|
||||
};
|
||||
|
||||
class DominoClock extends HTMLElement {
|
||||
elements: { [K in Face]: HTMLDivElement };
|
||||
|
||||
timer: number;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.timer = 0;
|
||||
this.innerHTML = TEMPLATE;
|
||||
this.elements = Object.fromEntries(
|
||||
Array.from(this.getElementsByTagName("div"))
|
||||
.filter(element => element.className === "face")
|
||||
.map(element => [isFace(element.id) && element.id, element])
|
||||
);
|
||||
this.paint = this.paint.bind(this);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.timer = window.setTimeout(this.paint, 250);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
window.clearTimeout(this.timer);
|
||||
}
|
||||
|
||||
tock(board: Face, time: number) {
|
||||
const dots = Array.from(this.elements[board].getElementsByTagName("div"));
|
||||
dots.forEach(element => {
|
||||
element.style.opacity = "0";
|
||||
});
|
||||
dots.forEach(element => {
|
||||
const row = MATRIX.find(i => Array.from(element.classList).includes(i[0]));
|
||||
if (!row) {
|
||||
console.log(`Didn't find a row for ${element.className}?`);
|
||||
return;
|
||||
}
|
||||
if (row[1].includes(time)) {
|
||||
element.style.opacity = "1";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
paint() {
|
||||
const now = new Date();
|
||||
const rawHours = now.getHours();
|
||||
const hours = rawHours > 12 ? rawHours - 12 : rawHours;
|
||||
this.tock("hours", hours);
|
||||
this.tock("minutes", Math.floor(now.getUTCMinutes() / 5));
|
||||
this.tock("seconds", Math.floor(now.getUTCSeconds() / 5));
|
||||
window.clearTimeout(this.timer);
|
||||
this.timer = window.setTimeout(this.paint, 250);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("domino-clock", DominoClock);
|
||||
export { DominoClock };
|
||||
export default DominoClock;
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"noImplicitAny": false,
|
||||
"module": "esnext",
|
||||
"target": "es2019",
|
||||
"lib": ["es2019", "dom", "dom.iterable"],
|
||||
"removeComments": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"allowJs": true,
|
||||
"strict": true,
|
||||
"baseUrl": "./",
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "node",
|
||||
"downlevelIteration": true,
|
||||
"noUnusedLocals": true /* Report errors on unused locals. */,
|
||||
"experimentalDecorators": true,
|
||||
"noUnusedParameters": true /* Report errors on unused parameters. */,
|
||||
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
|
||||
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
|
||||
"noUncheckedIndexedAccess": true /* Include 'undefined' in index signature results */,
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["./src/**/*"]
|
||||
"compilerOptions": {
|
||||
"target": "es2018",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noEmitOnError": true,
|
||||
"lib": ["es2017", "dom"],
|
||||
"strict": true,
|
||||
"esModuleInterop": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": false,
|
||||
"importHelpers": true,
|
||||
"outDir": "dist",
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
"baseUrl": "./",
|
||||
"rootDir": "./",
|
||||
"declaration": true,
|
||||
"incremental": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["./src/**/*"]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue