@phoenix-cg/v-tabs 0.1.21 → 0.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +9 -0
- package/.gitattributes +1 -0
- package/.vscode/extensions.json +8 -0
- package/.vscode/settings.json +11 -0
- package/README.md +27 -15
- package/eslint.config.js +32 -0
- package/export.js +3 -0
- package/index.html +13 -0
- package/jsconfig.json +8 -0
- package/package.json +21 -30
- package/src/App.vue +18 -35
- package/src/assets/base.css +86 -0
- package/src/assets/main.css +21 -0
- package/src/components/VTabs.vue +108 -85
- package/src/main.js +4 -6
- package/vite.config.js +25 -0
- package/vitest.config.js +14 -0
- package/.browserslistrc +0 -3
- package/.eslintrc.js +0 -26
- package/babel.config.js +0 -3
- package/dist/demo.html +0 -10
- package/dist/v-tabs.common.js +0 -6375
- package/dist/v-tabs.common.js.map +0 -1
- package/dist/v-tabs.css +0 -1
- package/dist/v-tabs.umd.js +0 -6385
- package/dist/v-tabs.umd.js.map +0 -1
- package/dist/v-tabs.umd.min.js +0 -2
- package/dist/v-tabs.umd.min.js.map +0 -1
- package/jest.config.js +0 -3
- package/public/index.html +0 -17
- package/src/assets/logo.png +0 -0
- package/src/export.js +0 -3
- package/tests/unit/VTabs.spec.js +0 -12
package/.editorconfig
ADDED
package/.gitattributes
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* text=auto eol=lf
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"explorer.fileNesting.enabled": true,
|
|
3
|
+
"explorer.fileNesting.patterns": {
|
|
4
|
+
"tsconfig.json": "tsconfig.*.json, env.d.ts",
|
|
5
|
+
"vite.config.*": "jsconfig*, vitest.config.*, cypress.config.*, playwright.config.*",
|
|
6
|
+
"package.json": "package-lock.json, pnpm*, .yarnrc*, yarn*, .eslint*, eslint*, .prettier*, prettier*, .editorconfig"
|
|
7
|
+
},
|
|
8
|
+
"editor.codeActionsOnSave": {
|
|
9
|
+
"source.fixAll": "explicit"
|
|
10
|
+
}
|
|
11
|
+
}
|
package/README.md
CHANGED
|
@@ -1,29 +1,41 @@
|
|
|
1
|
-
#
|
|
1
|
+
# tabs
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
This template should help get you started developing with Vue 3 in Vite.
|
|
4
|
+
|
|
5
|
+
## Recommended IDE Setup
|
|
6
|
+
|
|
7
|
+
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
|
8
|
+
|
|
9
|
+
## Customize configuration
|
|
10
|
+
|
|
11
|
+
See [Vite Configuration Reference](https://vite.dev/config/).
|
|
12
|
+
|
|
13
|
+
## Project Setup
|
|
14
|
+
|
|
15
|
+
```sh
|
|
5
16
|
npm install
|
|
6
17
|
```
|
|
7
18
|
|
|
8
|
-
###
|
|
9
|
-
```
|
|
10
|
-
npm run serve
|
|
11
|
-
```
|
|
19
|
+
### Compile and Hot-Reload for Development
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
```sh
|
|
22
|
+
npm run dev
|
|
14
23
|
```
|
|
24
|
+
|
|
25
|
+
### Compile and Minify for Production
|
|
26
|
+
|
|
27
|
+
```sh
|
|
15
28
|
npm run build
|
|
16
29
|
```
|
|
17
30
|
|
|
18
|
-
### Run
|
|
19
|
-
|
|
31
|
+
### Run Unit Tests with [Vitest](https://vitest.dev/)
|
|
32
|
+
|
|
33
|
+
```sh
|
|
20
34
|
npm run test:unit
|
|
21
35
|
```
|
|
22
36
|
|
|
23
|
-
###
|
|
24
|
-
|
|
37
|
+
### Lint with [ESLint](https://eslint.org/)
|
|
38
|
+
|
|
39
|
+
```sh
|
|
25
40
|
npm run lint
|
|
26
41
|
```
|
|
27
|
-
|
|
28
|
-
### Customize configuration
|
|
29
|
-
See [Configuration Reference](https://cli.vuejs.org/config/).
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import pluginVue from 'eslint-plugin-vue'
|
|
3
|
+
import globals from 'globals'
|
|
4
|
+
import pluginVitest from '@vitest/eslint-plugin'
|
|
5
|
+
|
|
6
|
+
export default [
|
|
7
|
+
{
|
|
8
|
+
name: 'app/files-to-lint',
|
|
9
|
+
files: ['**/*.{js,mjs,jsx,vue}'],
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
{
|
|
13
|
+
name: 'app/files-to-ignore',
|
|
14
|
+
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
languageOptions: {
|
|
19
|
+
globals: {
|
|
20
|
+
...globals.browser,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
js.configs.recommended,
|
|
26
|
+
...pluginVue.configs['flat/essential'],
|
|
27
|
+
|
|
28
|
+
{
|
|
29
|
+
...pluginVitest.configs.recommended,
|
|
30
|
+
files: ['src/**/__tests__/*'],
|
|
31
|
+
},
|
|
32
|
+
]
|
package/export.js
ADDED
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<link rel="icon" href="/favicon.ico">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Vite App</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.js"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/jsconfig.json
ADDED
package/package.json
CHANGED
|
@@ -1,39 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phoenix-cg/v-tabs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-beta.0",
|
|
4
4
|
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./export.js",
|
|
5
7
|
"scripts": {
|
|
6
|
-
"
|
|
7
|
-
"build": "
|
|
8
|
-
"
|
|
9
|
-
"
|
|
8
|
+
"dev": "vite",
|
|
9
|
+
"build": "vite build",
|
|
10
|
+
"preview": "vite preview",
|
|
11
|
+
"test:unit": "vitest",
|
|
12
|
+
"lint": "eslint . --fix"
|
|
10
13
|
},
|
|
11
14
|
"dependencies": {
|
|
12
|
-
"
|
|
13
|
-
"vue": "^2.6.11"
|
|
15
|
+
"vue": "^3.5.13"
|
|
14
16
|
},
|
|
15
|
-
"main": "./dist/v-tabs.common.js",
|
|
16
17
|
"devDependencies": {
|
|
17
|
-
"@
|
|
18
|
-
"@
|
|
19
|
-
"@
|
|
20
|
-
"@vue/
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"vue-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"directories": {
|
|
30
|
-
"test": "tests"
|
|
31
|
-
},
|
|
32
|
-
"repository": {
|
|
33
|
-
"type": "git",
|
|
34
|
-
"url": "git+ssh://git@bitbucket.org/cos_is/v-tabs.git"
|
|
35
|
-
},
|
|
36
|
-
"author": "Cos_is",
|
|
37
|
-
"license": "ISC",
|
|
38
|
-
"homepage": "https://bitbucket.org/cos_is/v-tabs#readme"
|
|
18
|
+
"@eslint/js": "^9.21.0",
|
|
19
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
|
20
|
+
"@vitest/eslint-plugin": "^1.1.36",
|
|
21
|
+
"@vue/test-utils": "^2.4.6",
|
|
22
|
+
"eslint": "^9.21.0",
|
|
23
|
+
"eslint-plugin-vue": "~10.0.0",
|
|
24
|
+
"globals": "^16.0.0",
|
|
25
|
+
"jsdom": "^26.0.0",
|
|
26
|
+
"vite": "^6.2.1",
|
|
27
|
+
"vite-plugin-vue-devtools": "^7.7.2",
|
|
28
|
+
"vitest": "^3.0.8"
|
|
29
|
+
}
|
|
39
30
|
}
|
package/src/App.vue
CHANGED
|
@@ -1,46 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
<v-tabs :list="list" v-model="currentTab"
|
|
2
|
+
<div>
|
|
3
|
+
<v-tabs with-slider :list="list" v-model="currentTab" />
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
|
-
<script>
|
|
8
|
-
import
|
|
7
|
+
<script setup>
|
|
8
|
+
import { ref } from 'vue'
|
|
9
|
+
import VTabs from './components/VTabs.vue'
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const list = [
|
|
12
|
+
{
|
|
13
|
+
_id: '0',
|
|
14
|
+
title: 'Tab one',
|
|
14
15
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
{
|
|
23
|
-
id: '1',
|
|
24
|
-
title: 'Tab two',
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: '2',
|
|
28
|
-
title: 'Tab three',
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
currentTab: null
|
|
32
|
-
}
|
|
16
|
+
{
|
|
17
|
+
_id: '1',
|
|
18
|
+
title: 'Tab two',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
_id: '2',
|
|
22
|
+
title: 'Tab three',
|
|
33
23
|
}
|
|
34
|
-
|
|
24
|
+
]
|
|
25
|
+
const currentTab = ref(null)
|
|
35
26
|
</script>
|
|
36
27
|
|
|
37
28
|
<style>
|
|
38
|
-
#app {
|
|
39
|
-
font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
40
|
-
-webkit-font-smoothing: antialiased;
|
|
41
|
-
-moz-osx-font-smoothing: grayscale;
|
|
42
|
-
text-align: center;
|
|
43
|
-
color: #2c3e50;
|
|
44
|
-
margin-top: 60px;
|
|
45
|
-
}
|
|
46
29
|
</style>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* color palette from <https://github.com/vuejs/theme> */
|
|
2
|
+
:root {
|
|
3
|
+
--vt-c-white: #ffffff;
|
|
4
|
+
--vt-c-white-soft: #f8f8f8;
|
|
5
|
+
--vt-c-white-mute: #f2f2f2;
|
|
6
|
+
|
|
7
|
+
--vt-c-black: #181818;
|
|
8
|
+
--vt-c-black-soft: #222222;
|
|
9
|
+
--vt-c-black-mute: #282828;
|
|
10
|
+
|
|
11
|
+
--vt-c-indigo: #2c3e50;
|
|
12
|
+
|
|
13
|
+
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
|
14
|
+
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
|
15
|
+
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
|
16
|
+
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
|
17
|
+
|
|
18
|
+
--vt-c-text-light-1: var(--vt-c-indigo);
|
|
19
|
+
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
|
20
|
+
--vt-c-text-dark-1: var(--vt-c-white);
|
|
21
|
+
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* semantic color variables for this project */
|
|
25
|
+
:root {
|
|
26
|
+
--color-background: var(--vt-c-white);
|
|
27
|
+
--color-background-soft: var(--vt-c-white-soft);
|
|
28
|
+
--color-background-mute: var(--vt-c-white-mute);
|
|
29
|
+
|
|
30
|
+
--color-border: var(--vt-c-divider-light-2);
|
|
31
|
+
--color-border-hover: var(--vt-c-divider-light-1);
|
|
32
|
+
|
|
33
|
+
--color-heading: var(--vt-c-text-light-1);
|
|
34
|
+
--color-text: #000;
|
|
35
|
+
|
|
36
|
+
--section-gap: 160px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@media (prefers-color-scheme: dark) {
|
|
40
|
+
:root {
|
|
41
|
+
--color-background: var(--vt-c-black);
|
|
42
|
+
--color-background-soft: var(--vt-c-black-soft);
|
|
43
|
+
--color-background-mute: var(--vt-c-black-mute);
|
|
44
|
+
|
|
45
|
+
--color-border: var(--vt-c-divider-dark-2);
|
|
46
|
+
--color-border-hover: var(--vt-c-divider-dark-1);
|
|
47
|
+
|
|
48
|
+
--color-heading: var(--vt-c-text-dark-1);
|
|
49
|
+
--color-text: #000;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
*,
|
|
54
|
+
*::before,
|
|
55
|
+
*::after {
|
|
56
|
+
box-sizing: border-box;
|
|
57
|
+
margin: 0;
|
|
58
|
+
font-weight: normal;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
body {
|
|
62
|
+
min-height: 100vh;
|
|
63
|
+
color: var(--color-text);
|
|
64
|
+
background: var(--color-background);
|
|
65
|
+
transition:
|
|
66
|
+
color 0.5s,
|
|
67
|
+
background-color 0.5s;
|
|
68
|
+
line-height: 1.6;
|
|
69
|
+
font-family:
|
|
70
|
+
Inter,
|
|
71
|
+
-apple-system,
|
|
72
|
+
BlinkMacSystemFont,
|
|
73
|
+
'Segoe UI',
|
|
74
|
+
Roboto,
|
|
75
|
+
Oxygen,
|
|
76
|
+
Ubuntu,
|
|
77
|
+
Cantarell,
|
|
78
|
+
'Fira Sans',
|
|
79
|
+
'Droid Sans',
|
|
80
|
+
'Helvetica Neue',
|
|
81
|
+
sans-serif;
|
|
82
|
+
font-size: 15px;
|
|
83
|
+
text-rendering: optimizeLegibility;
|
|
84
|
+
-webkit-font-smoothing: antialiased;
|
|
85
|
+
-moz-osx-font-smoothing: grayscale;
|
|
86
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@import './base.css';
|
|
2
|
+
|
|
3
|
+
#app {
|
|
4
|
+
max-width: 1280px;
|
|
5
|
+
margin: 0 auto;
|
|
6
|
+
padding: 2rem;
|
|
7
|
+
font-weight: normal;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@media (min-width: 1024px) {
|
|
11
|
+
body {
|
|
12
|
+
display: flex;
|
|
13
|
+
place-items: center;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#app {
|
|
17
|
+
display: grid;
|
|
18
|
+
grid-template-columns: 1fr 1fr;
|
|
19
|
+
padding: 0 2rem;
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/components/VTabs.vue
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="v-tabs" :class="[`__${direction}`]">
|
|
2
|
+
<div class="v-tabs" :class="[`__${props.direction}`]" ref="elRef">
|
|
3
3
|
<div class="v-tabs_inner">
|
|
4
4
|
<div
|
|
5
|
-
v-for="tab in list"
|
|
5
|
+
v-for="tab in props.list"
|
|
6
6
|
:key="tab[trackBy]"
|
|
7
7
|
ref="tabs"
|
|
8
8
|
class="v-tabs_tab"
|
|
9
9
|
:data-id="tab[trackBy]"
|
|
10
10
|
:class="{
|
|
11
|
-
__active:
|
|
11
|
+
__active: model && model[trackBy] === tab[trackBy],
|
|
12
12
|
_disabled: tab && tab._disabled
|
|
13
13
|
}"
|
|
14
14
|
@click="handleTabSelect(tab, $event)"
|
|
@@ -25,98 +25,121 @@
|
|
|
25
25
|
</slot>
|
|
26
26
|
</div>
|
|
27
27
|
</div>
|
|
28
|
-
<div v-if="withSlider" :style="sliderStyle" class="v-tabs_slider" />
|
|
28
|
+
<div v-if="props.withSlider" :style="sliderStyle" class="v-tabs_slider" />
|
|
29
29
|
</div>
|
|
30
30
|
</template>
|
|
31
31
|
|
|
32
|
-
<script>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
default: 'title'
|
|
46
|
-
},
|
|
47
|
-
list: {
|
|
48
|
-
type: Array,
|
|
49
|
-
required: true
|
|
50
|
-
},
|
|
51
|
-
value: {
|
|
52
|
-
type: Object
|
|
53
|
-
},
|
|
54
|
-
selectFirst: {
|
|
55
|
-
type: Boolean,
|
|
56
|
-
default: true
|
|
57
|
-
},
|
|
58
|
-
withSlider: {
|
|
59
|
-
type: Boolean,
|
|
60
|
-
default: false
|
|
61
|
-
},
|
|
62
|
-
initialTab: {
|
|
63
|
-
type: [Number, String],
|
|
64
|
-
default: null
|
|
65
|
-
},
|
|
66
|
-
wrapTitle: {
|
|
67
|
-
type: Boolean,
|
|
68
|
-
default: false
|
|
69
|
-
}
|
|
32
|
+
<script setup>
|
|
33
|
+
import {
|
|
34
|
+
nextTick,
|
|
35
|
+
onBeforeUnmount,
|
|
36
|
+
onMounted,
|
|
37
|
+
ref,
|
|
38
|
+
useTemplateRef,
|
|
39
|
+
watch
|
|
40
|
+
} from 'vue'
|
|
41
|
+
const props = defineProps({
|
|
42
|
+
direction: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: 'horizontal'
|
|
70
45
|
},
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
46
|
+
trackBy: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: '_id'
|
|
75
49
|
},
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
},
|
|
80
|
-
uid () {
|
|
81
|
-
return this._uid
|
|
82
|
-
}
|
|
50
|
+
label: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: 'title'
|
|
83
53
|
},
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
54
|
+
list: {
|
|
55
|
+
type: Array,
|
|
56
|
+
required: true
|
|
57
|
+
},
|
|
58
|
+
selectFirst: {
|
|
59
|
+
type: Boolean,
|
|
60
|
+
default: true
|
|
92
61
|
},
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
62
|
+
withSlider: {
|
|
63
|
+
type: Boolean,
|
|
64
|
+
default: false
|
|
65
|
+
},
|
|
66
|
+
initialTab: {
|
|
67
|
+
type: [Number, String],
|
|
68
|
+
default: null
|
|
69
|
+
},
|
|
70
|
+
wrapTitle: {
|
|
71
|
+
type: Boolean,
|
|
72
|
+
default: false
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
const model = defineModel()
|
|
76
|
+
const emit = defineEmits(['update:modelValue'])
|
|
77
|
+
const sliderStyle = ref({})
|
|
78
|
+
let resizeObserver = null
|
|
79
|
+
const tabsRefs = useTemplateRef('tabs')
|
|
80
|
+
const elRef = useTemplateRef('elRef')
|
|
81
|
+
|
|
82
|
+
function createResizeObserver () {
|
|
83
|
+
if (props.withSlider) {
|
|
84
|
+
resizeObserver = new ResizeObserver(() => {
|
|
85
|
+
calcSlider()
|
|
86
|
+
})
|
|
87
|
+
tabsRefs.value.forEach(tabEl => {
|
|
88
|
+
resizeObserver.observe(tabEl)
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function destroyResizeObserver () {
|
|
94
|
+
resizeObserver?.disconnect()
|
|
95
|
+
resizeObserver = null
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function handleTabSelect (tab) {
|
|
99
|
+
emit('update:modelValue', tab)
|
|
100
|
+
calcSlider()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function calcSlider () {
|
|
104
|
+
if (!props.withSlider || !elRef.value) {
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
const el = elRef.value
|
|
108
|
+
await nextTick()
|
|
109
|
+
const { left: tabsLeft } = el.getBoundingClientRect()
|
|
110
|
+
const [currentTabEl] = el.getElementsByClassName('__active')
|
|
111
|
+
if (currentTabEl) {
|
|
112
|
+
const {
|
|
113
|
+
left: currentTabLeft,
|
|
114
|
+
width
|
|
115
|
+
} = currentTabEl.getBoundingClientRect()
|
|
116
|
+
const tabsLeftScroll = el.scrollLeft
|
|
117
|
+
const leftPoisiton = currentTabLeft + tabsLeftScroll - tabsLeft
|
|
118
|
+
sliderStyle.value = {
|
|
119
|
+
transform: `translateX(${leftPoisiton}px)`,
|
|
120
|
+
width: `${width}px`
|
|
117
121
|
}
|
|
118
122
|
}
|
|
119
123
|
}
|
|
124
|
+
|
|
125
|
+
onMounted(() => {
|
|
126
|
+
if (props.selectFirst && props.list.length && !model.value) {
|
|
127
|
+
handleTabSelect(props.list[0])
|
|
128
|
+
}
|
|
129
|
+
if (props.initialTab && props.list.length && !model.value) {
|
|
130
|
+
const tab = props.list.find(tab => tab[props.trackBy] === props.initialTab)
|
|
131
|
+
tab && handleTabSelect(tab)
|
|
132
|
+
}
|
|
133
|
+
createResizeObserver()
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
onBeforeUnmount(() => {
|
|
137
|
+
destroyResizeObserver()
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
watch(model, () => {
|
|
141
|
+
props.withSlider && calcSlider()
|
|
142
|
+
})
|
|
120
143
|
</script>
|
|
121
144
|
|
|
122
145
|
<style>
|
package/src/main.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import App from './App.vue';
|
|
1
|
+
import './assets/main.css'
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { createApp } from 'vue'
|
|
4
|
+
import App from './App.vue'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
render: h => h(App)
|
|
8
|
-
}).$mount('#app');
|
|
6
|
+
createApp(App).mount('#app')
|
package/vite.config.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { fileURLToPath, URL } from 'node:url'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { defineConfig } from 'vite'
|
|
4
|
+
import vue from '@vitejs/plugin-vue'
|
|
5
|
+
import vueDevTools from 'vite-plugin-vue-devtools'
|
|
6
|
+
|
|
7
|
+
// https://vite.dev/config/
|
|
8
|
+
export default defineConfig({
|
|
9
|
+
build: {
|
|
10
|
+
lib: {
|
|
11
|
+
entry: path.resolve(__dirname, 'src/export.js'),
|
|
12
|
+
name: 'VTabs',
|
|
13
|
+
fileName: (format) => `v-tabs.${format}.js`
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
plugins: [
|
|
17
|
+
vue(),
|
|
18
|
+
vueDevTools(),
|
|
19
|
+
],
|
|
20
|
+
resolve: {
|
|
21
|
+
alias: {
|
|
22
|
+
'@': fileURLToPath(new URL('./src', import.meta.url))
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
})
|
package/vitest.config.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
2
|
+
import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
|
|
3
|
+
import viteConfig from './vite.config'
|
|
4
|
+
|
|
5
|
+
export default mergeConfig(
|
|
6
|
+
viteConfig,
|
|
7
|
+
defineConfig({
|
|
8
|
+
test: {
|
|
9
|
+
environment: 'jsdom',
|
|
10
|
+
exclude: [...configDefaults.exclude, 'e2e/**'],
|
|
11
|
+
root: fileURLToPath(new URL('./', import.meta.url)),
|
|
12
|
+
},
|
|
13
|
+
}),
|
|
14
|
+
)
|
package/.browserslistrc
DELETED