From 2c470625a77e4328306691ea417614ebedb44b7b78196ed8f13fca3b2dbcbae9 Mon Sep 17 00:00:00 2001 From: Janis Hutz Date: Fri, 28 Nov 2025 14:27:45 +0100 Subject: [PATCH] Prepare sliders, need to be fully completed and tested --- .gitignore | 23 +- eslint.config.mjs | 724 +++++++++++++++++++++++++++++++ index.html | 13 + package.json | 41 ++ public/vite.svg | 1 + src/App.vue | 22 + src/components/DoubleSlider.vue | 158 +++++++ src/components/NotchedSlider.vue | 228 ++++++++++ src/components/SingleSlider.vue | 0 src/index.ts | 9 + src/main.ts | 7 + src/style.css | 79 ++++ tsconfig.app.json | 16 + tsconfig.json | 7 + tsconfig.node.json | 26 ++ vite.config.ts | 31 ++ 16 files changed, 1375 insertions(+), 10 deletions(-) create mode 100644 eslint.config.mjs create mode 100644 index.html create mode 100644 package.json create mode 100644 public/vite.svg create mode 100644 src/App.vue create mode 100644 src/components/DoubleSlider.vue create mode 100644 src/components/NotchedSlider.vue create mode 100644 src/components/SingleSlider.vue create mode 100644 src/index.ts create mode 100644 src/main.ts create mode 100644 src/style.css create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore index a1e206a..4582ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,14 @@ -# ---> Vue -# gitignore template for Vue.js projects -# -# Recommended template: Node.gitignore - -# TODO: where does this rule come from? -docs/_book - -# TODO: where does this rule come from? -test/ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* +package-lock.json +node_modules +dist +dist-ssr +*.local diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..7d5f173 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,724 @@ +import eslint from '@eslint/js'; +import globals from 'globals'; +import stylistic from '@stylistic/eslint-plugin'; +import tseslint from 'typescript-eslint'; +import typescript from '@typescript-eslint/eslint-plugin'; +import vue from 'eslint-plugin-vue'; + +const style = { + 'plugins': { + '@stylistic': stylistic, + '@stylistic/js': stylistic, + '@stylistic/ts': stylistic, + }, + 'files': [ + '**/*.ts', + '**/*.js', + '**/*.mjs', + '**/*.cjs', + '**/*.tsx', + '**/*.jsx' + ], + 'rules': { + 'sort-imports': [ + 'warn', + { + 'ignoreCase': false, + 'ignoreDeclarationSort': false, + 'ignoreMemberSort': false, + 'memberSyntaxSortOrder': [ + 'none', + 'all', + 'multiple', + 'single' + ], + 'allowSeparatedGroups': false + } + ], + // Formatting + '@stylistic/array-bracket-newline': [ + 'error', + { + 'multiline': true, + 'minItems': 2 + } + ], + '@stylistic/array-bracket-spacing': [ + 'error', + 'always', + { + 'singleValue': true, + 'arraysInArrays': true, + 'objectsInArrays': true + } + ], + '@stylistic/array-element-newline': [ + 'error', + { + 'multiline': true, + 'minItems': 2 + } + ], + '@stylistic/arrow-parens': [ + 'error', + 'as-needed' + ], + '@stylistic/arrow-spacing': [ + 'error', + { + 'before': true, + 'after': true + } + ], + '@stylistic/block-spacing': [ + 'error', + 'always' + ], + '@stylistic/brace-style': [ + 'error', + '1tbs' + ], + '@stylistic/comma-spacing': [ + 'error', + { + 'before': false, + 'after': true + } + ], + '@stylistic/comma-style': [ + 'error', + 'last' + ], + '@stylistic/dot-location': [ + 'error', + 'property' + ], + '@stylistic/eol-last': [ + 'error', + 'always' + ], + '@stylistic/function-call-spacing': [ + 'error', + 'never' + ], + '@stylistic/function-paren-newline': [ + 'error', + { + 'minItems': 3 + } + ], + '@stylistic/function-call-argument-newline': [ + 'error', + 'consistent' + ], + '@stylistic/implicit-arrow-linebreak': [ + 'error', + 'beside' + ], + '@stylistic/indent': [ + 'error', + 4 + ], + '@stylistic/key-spacing': [ + 'error', + { + 'beforeColon': false, + 'afterColon': true + } + ], + '@stylistic/keyword-spacing': [ + 'error', + { + 'before': true, + 'after': true + } + ], + '@stylistic/lines-between-class-members': [ + 'error', + 'always' + ], + '@stylistic/max-len': [ + 'warn', + { + 'code': 120, + 'comments': 140, + 'ignoreComments': false, + 'ignoreUrls': true, + 'ignoreStrings': false + } + ], + '@stylistic/new-parens': [ + 'error', + 'always' + ], + '@stylistic/newline-per-chained-call': [ 'error' ], + '@stylistic/no-extra-parens': [ + 'error', + 'all', + { + 'nestedBinaryExpressions': false, + 'ternaryOperandBinaryExpressions': false, + 'ignoreJSX': 'multi-line', + 'nestedConditionalExpressions': false + } + ], + '@stylistic/no-extra-semi': 'error', + '@stylistic/no-floating-decimal': 'error', + '@stylistic/no-mixed-operators': 'error', + '@stylistic/no-mixed-spaces-and-tabs': 'error', + '@stylistic/no-multi-spaces': 'error', + '@stylistic/no-multiple-empty-lines': [ + 'error', + { + 'max': 3, + 'maxEOF': 2 + } + ], + '@stylistic/no-tabs': 'error', + '@stylistic/no-trailing-spaces': 'error', + '@stylistic/no-whitespace-before-property': 'error', + '@stylistic/object-curly-newline': [ + 'error', + { + 'multiline': true, + 'minProperties': 1 + } + ], + '@stylistic/object-curly-spacing': [ + 'error', + 'always' + ], + '@stylistic/object-property-newline': 'error', + '@stylistic/operator-linebreak': [ + 'error', + 'before' + ], + '@stylistic/one-var-declaration-per-line': 'error', + '@stylistic/padded-blocks': [ + 'error', + { + 'blocks': 'never', + 'classes': 'always', + 'switches': 'never', + } + ], + + // Padding lines. The most in-depth part of this config + '@stylistic/padding-line-between-statements': [ + 'error', + // Variables, Constants + { + 'blankLine': 'never', + 'prev': 'var', + 'next': 'var' + }, + { + 'blankLine': 'never', + 'prev': 'let', + 'next': 'let' + }, + { + 'blankLine': 'never', + 'prev': 'const', + 'next': 'const' + }, + { + 'blankLine': 'always', + 'prev': 'var', + 'next': [ + 'block', + 'block-like', + 'break', + 'cjs-export', + 'cjs-import', + 'class', + 'const', + 'continue', + 'debugger', + 'directive', + 'do', + 'empty', + 'export', + 'expression', + 'for', + 'function', + 'if', + 'iife', + 'import', + 'let', + 'return', + 'switch', + 'throw', + 'try', + 'var', + 'with' + ] + }, + { + 'blankLine': 'always', + 'prev': 'let', + 'next': [ + 'block', + 'block-like', + 'break', + 'cjs-export', + 'cjs-import', + 'class', + 'const', + 'continue', + 'debugger', + 'directive', + 'do', + 'empty', + 'export', + 'expression', + 'for', + 'function', + 'if', + 'iife', + 'import', + 'return', + 'switch', + 'throw', + 'try', + 'var', + 'while', + 'with' + ] + }, + { + 'blankLine': 'always', + 'prev': 'const', + 'next': [ + 'block', + 'block-like', + 'break', + 'cjs-export', + 'cjs-import', + 'class', + 'continue', + 'debugger', + 'directive', + 'do', + 'empty', + 'export', + 'expression', + 'for', + 'function', + 'if', + 'iife', + 'import', + 'let', + 'return', + 'switch', + 'throw', + 'try', + 'var', + 'while', + 'with' + ] + }, + // Import + { + 'blankLine': 'never', + 'prev': 'import', + 'next': 'import' + }, + { + 'blankLine': 'never', + 'prev': 'cjs-import', + 'next': 'cjs-import' + }, + { + 'blankLine': 'always', + 'prev': [ + 'block', + 'block-like', + 'break', + 'cjs-export', + 'class', + 'const', + 'continue', + 'debugger', + 'directive', + 'do', + 'empty', + 'export', + 'expression', + 'for', + 'function', + 'if', + 'iife', + 'let', + 'return', + 'switch', + 'throw', + 'try', + 'var', + 'while', + 'with' + ], + 'next': 'cjs-import' + }, + { + 'blankLine': 'always', + 'prev': 'cjs-import', + 'next': [ + 'block', + 'block-like', + 'break', + 'cjs-export', + 'class', + 'const', + 'continue', + 'debugger', + 'directive', + 'do', + 'empty', + 'export', + 'expression', + 'for', + 'function', + 'if', + 'iife', + 'let', + 'return', + 'switch', + 'throw', + 'try', + 'var', + 'while', + 'with' + ] + }, + { + 'blankLine': 'always', + 'prev': [ + 'block', + 'block-like', + 'break', + 'cjs-export', + 'class', + 'const', + 'continue', + 'debugger', + 'directive', + 'do', + 'empty', + 'export', + 'expression', + 'for', + 'function', + 'if', + 'iife', + 'let', + 'return', + 'switch', + 'throw', + 'try', + 'var', + 'while', + 'with' + ], + 'next': 'import' + }, + { + 'blankLine': 'always', + 'prev': 'import', + 'next': [ + 'block', + 'block-like', + 'break', + 'cjs-export', + 'class', + 'const', + 'continue', + 'debugger', + 'directive', + 'do', + 'empty', + 'export', + 'expression', + 'for', + 'function', + 'if', + 'iife', + 'let', + 'return', + 'switch', + 'throw', + 'try', + 'var', + 'while', + 'with' + ] + }, + // If + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'if' + }, + { + 'blankLine': 'always', + 'prev': 'if', + 'next': '*' + }, + // For + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'for' + }, + { + 'blankLine': 'always', + 'prev': 'for', + 'next': '*' + }, + // While + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'while' + }, + { + 'blankLine': 'always', + 'prev': 'while', + 'next': '*' + }, + // Functions + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'function' + }, + { + 'blankLine': 'always', + 'prev': 'function', + 'next': '*' + }, + // Block Statements + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'block-like' + }, + { + 'blankLine': 'always', + 'prev': 'block-like', + 'next': '*' + }, + // Switch + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'switch' + }, + { + 'blankLine': 'always', + 'prev': 'switch', + 'next': '*' + }, + // Try-Catch + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'try' + }, + { + 'blankLine': 'always', + 'prev': 'try', + 'next': '*' + }, + // Throw + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'throw' + }, + { + 'blankLine': 'always', + 'prev': 'throw', + 'next': '*' + }, + // Return + { + 'blankLine': 'never', + 'prev': 'return', + 'next': '*' + }, + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'return' + }, + // Export + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'export' + }, + { + 'blankLine': 'always', + 'prev': 'export', + 'next': '*' + }, + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'cjs-export' + }, + { + 'blankLine': 'always', + 'prev': 'cjs-export', + 'next': '*' + }, + // Classes + { + 'blankLine': 'always', + 'prev': '*', + 'next': 'class' + }, + { + 'blankLine': 'always', + 'prev': 'class', + 'next': '*' + }, + ], + '@stylistic/quote-props': [ + 'error', + 'always' + ], + '@stylistic/quotes': [ + 'error', + 'single' + ], + '@stylistic/rest-spread-spacing': [ + 'error', + 'never' + ], + '@stylistic/semi': [ + 'error', + 'always' + ], + '@stylistic/semi-spacing': [ + 'error', + { + 'before': false, + 'after': true + } + ], + '@stylistic/semi-style': [ + 'error', + 'last' + ], + '@stylistic/space-before-blocks': [ + 'error', + 'always' + ], + '@stylistic/space-before-function-paren': [ + 'error', + 'always' + ], + '@stylistic/space-in-parens': [ + 'error', + 'always' + ], + '@stylistic/space-infix-ops': [ + 'error', + { + 'int32Hint': false + } + ], + '@stylistic/space-unary-ops': 'error', + '@stylistic/spaced-comment': [ + 'error', + 'always' + ], + '@stylistic/template-curly-spacing': [ + 'error', + 'always' + ], + '@stylistic/switch-colon-spacing': 'error', + '@stylistic/wrap-iife': [ + 'error', + 'inside' + ], + '@stylistic/wrap-regex': 'error', + '@stylistic/ts/type-annotation-spacing': 'error', + } +}; + +/** @type {import('eslint').Linter.Config} */ +export default tseslint.config( + // Base JavaScript rules + eslint.configs.recommended, + tseslint.configs.recommended, + style, + + // Vue support (including TS and JSX inside SFCs) + { + 'files': [ '**/*.vue' ], + 'languageOptions': { + 'sourceType': 'module', + 'ecmaVersion': 'latest', + 'globals': globals.browser, + 'parserOptions': { + 'parser': tseslint.parser, + }, + }, + 'plugins': { + 'vue': vue, + '@stylistic': stylistic, + '@stylistic/js': stylistic, + '@stylistic/ts': stylistic, + '@typescript-eslint': typescript, + }, + 'extends': [ + eslint.configs.recommended, + ...vue.configs['flat/recommended'] + ], + 'rules': { + ...typescript.configs.recommended.rules, + ...style.rules, + + // Vue specific rules + '@stylistic/indent': 'off', + 'vue/html-indent': [ + 'error', + 4 + ], + 'vue/html-comment-indent': [ + 'error', + 4 + ], + 'vue/script-indent': [ + 'error', + 4, + { + 'baseIndent': 1, + 'switchCase': 1 + } + ], + 'vue/html-self-closing': [ + 'error', + { + 'html': { + 'void': 'never', + 'normal': 'never', + 'component': 'always' + }, + 'svg': 'always', + 'math': 'never' + } + ], + 'vue/max-attributes-per-line': [ + 'error', + { + 'singleline': 3, + 'multiline': 1, + } + ], + }, + }, +); diff --git a/index.html b/index.html new file mode 100644 index 0000000..d51020d --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + vue3-slider + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..8302f19 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "vue3-slider", + "private": false, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc -b && vite build", + "preview": "vite preview" + }, + "main": "./dist/fileName.umd.js", + "module": "./dist/fileName.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/fileName.esm.js", + "require": "./dist/fileName.js" + } + }, + "files": [ + "dist", + "src" + ], + "peerDependencies": { + "vue": "^3.5.24" + }, + "devDependencies": { + "@eslint/js": "^9.39.1", + "@stylistic/eslint-plugin": "^5.6.1", + "@types/node": "^24.10.1", + "@vitejs/plugin-vue": "^6.0.1", + "@vue/tsconfig": "^0.8.1", + "eslint-plugin-vue": "^10.6.2", + "typescript": "~5.9.3", + "typescript-eslint": "^8.48.0", + "vite": "^7.2.4", + "vite-plugin-dts": "^4.5.4", + "vue-tsc": "^3.1.4", + "vue": "^3.5.24" + } +} diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..a77ffb4 --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..d8aa617 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/components/DoubleSlider.vue b/src/components/DoubleSlider.vue new file mode 100644 index 0000000..8615661 --- /dev/null +++ b/src/components/DoubleSlider.vue @@ -0,0 +1,158 @@ + + + + + + diff --git a/src/components/NotchedSlider.vue b/src/components/NotchedSlider.vue new file mode 100644 index 0000000..311f8f9 --- /dev/null +++ b/src/components/NotchedSlider.vue @@ -0,0 +1,228 @@ + + + + + + + diff --git a/src/components/SingleSlider.vue b/src/components/SingleSlider.vue new file mode 100644 index 0000000..473a0f4 diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..389f01c --- /dev/null +++ b/src/index.ts @@ -0,0 +1,9 @@ +import DoubleSlider from './components/DoubleSlider.vue'; +import NotchedSlider from './components/NotchedSlider.vue'; +import SingleSlider from './components/SingleSlider.vue'; + +export { + NotchedSlider, + SingleSlider, + DoubleSlider +}; diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..0f74120 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,7 @@ +import './style.css'; +import App from './App.vue'; +import { + createApp +} from 'vue'; + +createApp( App ).mount( '#app' ); diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..aaeacf1 --- /dev/null +++ b/src/style.css @@ -0,0 +1,79 @@ +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..b4cb103 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,16 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "types": ["vite/client"], + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6099fb5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..4dc1770 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..f6c7e5f --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,31 @@ +import { + defineConfig +} from 'vite'; +import dts from 'vite-plugin-dts'; +import { + resolve +} from 'node:path'; +import vue from '@vitejs/plugin-vue'; + +// https://vitejs.dev/config/ +export default defineConfig( { + 'plugins': [ + vue(), + dts() + ], + 'build': { + 'lib': { + 'entry': resolve( __dirname, 'src/index.ts' ), + 'name': 'TestComponent', + 'fileName': 'test-component', + }, + 'rollupOptions': { + 'external': [ 'vue' ], + 'output': { + 'globals': { + 'vue': 'Vue', + }, + }, + }, + }, +} );