commit 5b9bf635913db86ad2a505ef1385ea4b3847f1e2 Author: jxxghp Date: Sat Jun 24 08:22:59 2023 +0800 first commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..63c8c4cc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,38 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Matches multiple files with brace expansion notation +# Set default charset +[*.{js,py}] +charset = utf-8 + +# 4 space indentation +[*.py] +indent_style = space +indent_size = 4 + +# 2 space indentation +[*.{vue,scss,ts}] +indent_style = space +indent_size = 2 + +# Tab indentation (no size specified) +[Makefile] +indent_style = tab + +# Indentation override for all JS under lib directory +[lib/**.js] +indent_style = space +indent_size = 2 + +# Matches the exact files either package.json or .travis.yml +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..0c545731 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,243 @@ +module.exports = { + env: { + browser: true, + es2021: true, + }, + extends: [ + '@antfu/eslint-config-vue', + 'plugin:vue/vue3-recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:promise/recommended', + 'plugin:sonarjs/recommended', + 'plugin:@typescript-eslint/recommended', + + // 'plugin:unicorn/recommended', + ], + parser: 'vue-eslint-parser', + parserOptions: { + ecmaVersion: 13, + parser: '@typescript-eslint/parser', + sourceType: 'module', + }, + plugins: [ + 'vue', + '@typescript-eslint', + 'regex', + ], + ignorePatterns: ['src/@iconify/*.js', 'node_modules', 'dist', '*.d.ts'], + rules: { + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + + // indentation (Already present in TypeScript) + 'comma-spacing': ['error', { before: false, after: true }], + 'key-spacing': ['error', { afterColon: true }], + + 'vue/first-attribute-linebreak': ['error', { + singleline: 'beside', + multiline: 'below', + }], + + 'antfu/top-level-function': 'off', + + // indentation (Already present in TypeScript) + 'indent': ['error', 2], + + // Enforce trailing comma (Already present in TypeScript) + 'comma-dangle': ['error', 'always-multiline'], + + // Enforce consistent spacing inside braces of object (Already present in TypeScript) + 'object-curly-spacing': ['error', 'always'], + + // Disable max-len + 'max-len': 'off', + + // we don't want it + 'semi': ['error', 'never'], + + // add parens ony when required in arrow function + 'arrow-parens': ['error', 'as-needed'], + + // add new line above comment + 'newline-before-return': 'error', + + // add new line above comment + 'lines-around-comment': [ + 'error', + { + beforeBlockComment: true, + beforeLineComment: true, + allowBlockStart: true, + allowClassStart: true, + allowObjectStart: true, + allowArrayStart: true, + }, + ], + + // Ignore _ as unused variable + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_+$' }], + + 'array-element-newline': ['error', 'consistent'], + 'array-bracket-newline': ['error', 'consistent'], + + 'vue/multi-word-component-names': 'off', + + 'padding-line-between-statements': [ + 'error', + { blankLine: 'always', prev: 'expression', next: 'const' }, + { blankLine: 'always', prev: 'const', next: 'expression' }, + { blankLine: 'always', prev: 'multiline-const', next: '*' }, + { blankLine: 'always', prev: '*', next: 'multiline-const' }, + ], + + // Plugin: eslint-plugin-import + 'import/prefer-default-export': 'off', + 'import/newline-after-import': ['error', { count: 1 }], + 'no-restricted-imports': ['error', 'vuetify/components'], + + // For omitting extension for ts files + 'import/extensions': [ + 'error', + 'ignorePackages', + { + js: 'never', + jsx: 'never', + ts: 'never', + tsx: 'never', + }, + ], + + // ignore virtual files + 'import/no-unresolved': [2, { + ignore: [ + '~pages$', + 'virtual:generated-layouts', + + // Ignore vite's ?raw imports + '.*\?raw', + ], + }], + + // Thanks: https://stackoverflow.com/a/63961972/10796681 + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': ['error'], + + '@typescript-eslint/consistent-type-imports': 'error', + + // Plugin: eslint-plugin-promise + 'promise/always-return': 'off', + 'promise/catch-or-return': 'off', + + // ESLint plugin vue + 'vue/block-tag-newline': 'error', + 'vue/component-api-style': 'error', + 'vue/component-name-in-template-casing': ['error', 'PascalCase', { registeredComponentsOnly: false }], + 'vue/custom-event-name-casing': ['error', 'camelCase', { + ignores: [ + '/^(click):[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?/', + ], + }], + 'vue/define-macros-order': 'error', + 'vue/html-comment-content-newline': 'error', + 'vue/html-comment-content-spacing': 'error', + 'vue/html-comment-indent': 'error', + 'vue/match-component-file-name': 'error', + 'vue/no-child-content': 'error', + 'vue/require-default-prop': 'off', + + // NOTE this rule only supported in SFC, Users of the unplugin-vue-define-options should disable that rule: https://github.com/vuejs/eslint-plugin-vue/issues/1886 + // 'vue/no-duplicate-attr-inheritance': 'error', + 'vue/no-empty-component-block': 'error', + 'vue/no-multiple-objects-in-class': 'error', + 'vue/no-reserved-component-names': 'error', + 'vue/no-template-target-blank': 'error', + 'vue/no-useless-mustaches': 'error', + 'vue/no-useless-v-bind': 'error', + 'vue/padding-line-between-blocks': 'error', + 'vue/prefer-separate-static-class': 'error', + 'vue/prefer-true-attribute-shorthand': 'error', + 'vue/v-on-function-call': 'error', + 'vue/no-restricted-class': ['error', '/^(p|m)(l|r)-/'], + 'vue/valid-v-slot': ['error', { + allowModifiers: true, + }], + + // -- Extension Rules + 'vue/no-irregular-whitespace': 'error', + 'vue/template-curly-spacing': 'error', + + // -- Sonarlint + 'sonarjs/no-duplicate-string': 'off', + 'sonarjs/no-nested-template-literals': 'off', + + // -- Unicorn + // 'unicorn/filename-case': 'off', + // 'unicorn/prevent-abbreviations': ['error', { + // replacements: { + // props: false, + // }, + // }], + + // Internal Rules + 'valid-appcardcode-code-prop': 'error', + 'valid-appcardcode-demo-sfc': 'error', + + // https://github.com/gmullerb/eslint-plugin-regex + 'regex/invalid': [ + 'error', + [ + { + regex: '@/assets/images', + replacement: '@images', + message: 'Use \'@images\' path alias for image imports', + }, + { + regex: '@/styles', + replacement: '@styles', + message: 'Use \'@styles\' path alias for importing styles from \'src/styles\'', + }, + + // { + // id: 'Disallow icon of icon library', + // regex: 'tabler-\\w', + // message: 'Only \'mdi\' icons are allowed', + // }, + + { + regex: '@core/\\w', + message: 'You can\'t use @core when you are in @layouts module', + files: { + inspect: '@layouts/.*', + }, + }, + { + regex: 'useLayouts\\(', + message: '`useLayouts` composable is only allowed in @layouts & @core directory. Please use `useThemeConfig` composable instead.', + files: { + inspect: '^(?!.*(@core|@layouts)).*', + }, + }, + { + regex: 'import axios from \'axios\'', + replacement: 'import axios from \'@axios\'', + message: 'Use axios instances created in \'src/plugin/axios.ts\' instead of unconfigured axios', + files: { + ignore: '^.*plugins/axios.ts.*', + }, + }, + ], + + // Ignore files + '\.eslintrc\.js', + ], + }, + settings: { + 'import/resolver': { + node: { + extensions: ['.ts', '.js', '.tsx', '.jsx', '.mjs', '.png', '.jpg'], + }, + typescript: {}, + }, + }, +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..52fb4278 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +!.vscode/*.code-snippets +!.vscode/tours +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +.yarn + +# iconify dist files +src/@iconify/*.js diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..db4c6d9b --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +dist +node_modules \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000..9b8b61a5 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,20 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "jsxBracketSameLine": false, + "jsxSingleQuote": true, + "printWidth": 120, + "proseWrap": "preserve", + "quoteProps": "as-needed", + "requirePragma": false, + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "all", + "useTabs": false, + "vueIndentScriptAndStyle": false, + "endOfLine": "lf", + "singleAttributePerLine": true +} \ No newline at end of file diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 00000000..2d810175 --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,34 @@ +{ + "extends": [ + "stylelint-config-standard-scss", + "stylelint-config-idiomatic-order" + ], + "plugins": [ + "stylelint-use-logical-spec" + ], + "overrides": [ + { + "files": [ + "**/*.scss" + ], + "customSyntax": "postcss-scss" + }, + { + "files": [ + "**/*.vue" + ], + "customSyntax": "postcss-html" + } + ], + "rules": { + "max-line-length": [ + 120, + { + "ignore": "comments" + } + ], + "liberty/use-logical-spec": true, + "selector-class-pattern": null, + "color-function-notation": null + } +} diff --git a/.vscode/anchor-comments.code-snippets b/.vscode/anchor-comments.code-snippets new file mode 100644 index 00000000..7342c887 --- /dev/null +++ b/.vscode/anchor-comments.code-snippets @@ -0,0 +1,23 @@ +{ + "Add hand emoji": { + "prefix": "cm-hand-emoji", + "body": [ + "👉" + ], + "description": "Add hand emoji" + }, + "Add info emoji": { + "prefix": "cm-info-emoji", + "body": [ + "â„šī¸" + ], + "description": "Add info emoji" + }, + "Add warning emoji": { + "prefix": "cm-warning-emoji", + "body": [ + "❗" + ], + "description": "Add warning emoji" + } +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..4286b3f2 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,15 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "mgmcdermott.vscode-language-babel", + "editorconfig.editorconfig", + "xabikos.javascriptsnippets", + "stylelint.vscode-stylelint", + "fabiospampinato.vscode-highlight", + "github.vscode-pull-request-github", + "vue.volar", + "antfu.iconify", + "cipchk.cssrem", + "matijao.vue-nuxt-snippets" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..39a5287a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,113 @@ +{ + "editor.formatOnSave": true, + "javascript.updateImportsOnFileMove.enabled": "always", + "[javascript]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + "[typescript]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.autoClosingBrackets": "always" + }, + "[markdown]": { + "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" + }, + // SCSS + "[scss]": { + "editor.defaultFormatter": "stylelint.vscode-stylelint" + }, + // JSON + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features" + }, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features" + }, + // Vue + "[vue]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + }, + // Extension: Volar + "volar.preview.port": 3000, + "volar.completion.preferredTagNameCase": "pascal", + // Extension: ESLint + "eslint.options": { + "rulePaths": [ + "eslint-internal-rules" + ] + }, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true, + "source.fixAll.stylelint": true, + "source.organizeImports": true, + }, + "eslint.alwaysShowStatus": true, + "eslint.format.enable": true, + "eslint.packageManager": "yarn", + // Extension: Stylelint + "stylelint.packageManager": "yarn", + "stylelint.validate": [ + "css", + "scss", + "vue" + ], + // Extension: Spell Checker + "cSpell.words": [ + "Composables", + "Customizer", + "flagpack", + "Iconify", + "psudo", + "stylelint", + "touchless", + "triggerer", + "vuetify" + ], + // Extension: Comment Anchors + "commentAnchors.tags.list": [ + { + "tag": "â„šī¸", + "scope": "hidden", + // This color is taken from "Better Comments" Extension (?) + "highlightColor": "#3498DB", + "styleComment": true, + "isItalic": false, + }, + { + "tag": "👉", + "scope": "file", + // This color is taken from "Better Comments" Extension (*) + "highlightColor": "#98C379", + "styleComment": true, + "isItalic": false + }, + { + "tag": "❗", + "scope": "hidden", + // This color is taken from "Better Comments" Extension (*) + "highlightColor": "#FF2D00", + "styleComment": true, + "isItalic": false, + }, + ], + // Extension: fabiospampinato.vscode-highlight + "highlight.regexFlags": "gi", + "highlight.regexes": { + // We flaged this for enforcing logical CSS properties + "(100vh|translate|margin:|padding:|margin-left|margin-right|rotate|text-align|border-top|border-right|border-bottom|border-left|float|background-position|transform|width|height|top|left|bottom|right|float|clear|(p|m)(l|r)-|border-(start|end)-(start|end)-radius)": [ + { + // "rangeBehavior": 1, + "borderWidth": "1px", + "borderColor": "tomato", + "borderStyle": "solid" + } + ], + "(overflow-x:|overflow-y:)": [ + { + // "rangeBehavior": 1, + "borderWidth": "1px", + "borderColor": "green", + "borderStyle": "solid" + } + ] + } +} \ No newline at end of file diff --git a/.vscode/vue-ts.code-snippets b/.vscode/vue-ts.code-snippets new file mode 100644 index 00000000..360713ab --- /dev/null +++ b/.vscode/vue-ts.code-snippets @@ -0,0 +1,18 @@ +{ + "Vue TS - DefineProps": { + "prefix": "dprops", + "body": [ + "defineProps<${1:Props}>()" + ], + "description": "DefineProps in script setup" + }, + "Vue TS - Props interface": { + "prefix": "iprops", + "body": [ + "interface Props {", + " ${1}", + "}" + ], + "description": "Create props interface in script setup" + } +} diff --git a/.vscode/vue.code-snippets b/.vscode/vue.code-snippets new file mode 100644 index 00000000..68d4bf01 --- /dev/null +++ b/.vscode/vue.code-snippets @@ -0,0 +1,63 @@ +{ + "script": { + "prefix": "vue-sfc-ts", + "body": [ + "", + "", + "", + "", + "", + "" + ], + "description": "Vue SFC Typescript" + }, + "template": { + "scope": "vue", + "prefix": "template", + "body": [ + "" + ], + "description": "Create