Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 112 additions & 14 deletions packages/simplebar-vue/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@
<div
class="simplebar-content-wrapper"
ref="scrollElement"
v-on="{
...($listeners.scroll && {
scroll: $listeners.scroll,
})
}"
@scroll="$emit('scroll', $event)"
>
<div class="simplebar-content" ref="contentElement">
<slot></slot>
Expand All @@ -31,23 +27,125 @@
</div>
</div>
</template>

<script>
// @ts-check
import SimpleBar from 'simplebar';
import { lifecycleEventNames } from './utils.js'

export default {
name: 'simplebar-vue',
props: {
/**
* By default SimpleBar automatically hides the scrollbar if the user is not scrolling
* (it emulates Mac OSX Lion's scrollbar). You can make the scrollbar always visible
* by passing `false`.
*
* Default value is `true`.
*
* You can also control the animation via CSS as it's a simple CSS opacity transition.
*/
autoHide: { type: Boolean, default: undefined },

/**
* It is possible to change the default class names that SimpleBar uses.
* To get your own styles to work refer to simplebar.css to get an idea how to setup your css.
* - `content` represents the wrapper for the content being scrolled.
* - `scrollContent` represents the container containing the elements being scrolled.
* - `scrollbar` defines the style of the scrollbar with which the user can interact to scroll the content.
* - `track` styles the area surrounding the `scrollbar`.
*
* ```js
* classNames: {
* // defaults
* content: 'simplebar-content',
* scrollContent: 'simplebar-scroll-content',
* scrollbar: 'simplebar-scrollbar',
* track: 'simplebar-track'
* }
* ```
*/
classNames: Object,

/**
* Force the track to be visible (same behaviour as `overflow: scroll`).
* Can be `boolean | 'x' | 'y'`, defaults to `false`, which behaves like `overflow: auto`.
*/
forceVisible: {
type: [Boolean, String],
validator: v => typeof v === 'boolean' || v === 'x' || v === 'y',
default: undefined
},

/**
* Set custom aria-label attribute for users with screen reader.
*/
ariaLabel: String,

/**
* Activate RTL support by passing `'rtl'`.
* You will also need a css rule with `direction: rtl`.
*/
direction: {
type: String,
validator: v => v === 'ltr' || v === 'rtl'
},

/**
* Define the delay until the scrollbar hides. Has no effect if `autoHide` is `false`.
* Default value is `1000`.
*/
timeout: Number,

/**
* Controls the click on track behaviour.
* Default to `true`.
*/
clickOnTrack: { type: Boolean, default: undefined },

/**
* Controls the min size of the scrollbar in `px`.
* Default is `25`.
*/
scrollbarMinSize: Number,

/**
* Controls the max size of the scrollbar in `px`.
* Default is `0` (no max size).
*/
scrollbarMaxSize: Number
},

// @ts-ignore
emits: ['scroll'],

/**
* @returns {{ SimpleBar?: SimpleBar; scrollElement?: HTMLDivElement; contentElement?: HTMLDivElement }}
*/
data() { return { }; },

mounted () {
// @ts-ignore (`getOptions` needs to be added to the type definition file)
const options = SimpleBar.getOptions(this.$refs.element.attributes);
this.SimpleBar = new SimpleBar(this.$refs.element, options);

for(const [key, value] of Object.entries(this.$props))
if(value != undefined && typeof value !== "function")
options[key] = value;

// @ts-ignore (unable to type cast `$el`)
this.SimpleBar = new SimpleBar(this.$el, options);
// @ts-ignore (unable to type cast `$refs`)
this.scrollElement = this.$refs.scrollElement;
// @ts-ignore (unable to type cast `$refs`)
this.contentElement = this.$refs.contentElement;
},
computed: {
scrollElement () {
return this.$refs.scrollElement;
},
contentElement () {
return this.$refs.contentElement;
}
[lifecycleEventNames.beforeUnmount]() {
// unMount is not present in types package https://github.com/Grsmto/simplebar/blob/6125d4ac0897c02a82432441aa3bae5e6c6ccb87/packages/simplebar/src/simplebar.js#L925
// @ts-ignore
this.SimpleBar?.unMount();
this.SimpleBar = undefined;
},
methods: {
recalculate () { this.SimpleBar?.recalculate(); }
}
}
</script>
12 changes: 9 additions & 3 deletions packages/simplebar-vue/jest-unit.config.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
const { isVue3 } = require('vue-demi');

module.exports = {
transform: {
'^.+\\.js?$': 'babel-jest',
'^.+\\.vue$': 'vue-jest'
'^.+\\.vue$': isVue3 ? 'vue-jest' : 'vue-jest2',
},
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$'],
moduleFileExtensions: ['js'],
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: ['jest-serializer-vue'],
setupFiles: ['<rootDir>/tests/testsSetup.js']
setupFiles: ['<rootDir>/tests/testsSetup.js'],
testURL: "http://localhost/"
};
57 changes: 27 additions & 30 deletions packages/simplebar-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,48 @@
},
"main": "dist/simplebar-vue.js",
"module": "dist/simplebar-vue.esm.js",
"types": "dist/simplebar-vue.d.ts",
"bugs": "https://github.com/grsmto/simplebar/issues",
"homepage": "https://grsmto.github.io/simplebar/",
"license": "MIT",
"scripts": {
"build": "rollup -c",
"test": "jest -c jest-unit.config.js",
"build": "rollup -c && cp simplebar-vue.d.ts dist/simplebar-vue.d.ts",
"jest": "jest -c jest-unit.config.js",
"version": "yarn build",
"precommit": "lint-staged"
"precommit": "lint-staged",
"test:2": "npm run use-vue:2 && npm run jest",
"test:2.7": "npm run use-vue:2.7 && npm run jest",
"test:3": "npm run use-vue:3 && npm run jest",
"test": "npm run test:2 && npm run test:2.7 && npm run test:3",
"use-vue:2": "node scripts/swap-vue.js 2 && vue-demi-switch 2",
"use-vue:2.7": "node scripts/swap-vue.js 2.7 && vue-demi-switch 2.7",
"use-vue:3": "node scripts/swap-vue.js 3 && vue-demi-switch 3"
},
"dependencies": {
"core-js": "^3.0.1",
"simplebar": "^5.3.9"
},
"peerDependencies": {
"vue": "^2.5.17"
"vue": "^3.0.0-0 || ^2.6.14"
},
"devDependencies": {
"@babel/core": "^7.4.3",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-jest": "^23.0.1",
"@vue/compiler-sfc": "^3.2.45",
"@vue/composition-api": "^1.7.1",
"@vue/test-utils": "^2.0.0-0",
"@vue/test-utils-vue2": "npm:@vue/test-utils@~1",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^28.1.0",
"jest-serializer-vue": "^2.0.2",
"rollup-plugin-vue": "4.3.2",
"vue": "^2.5.22",
"vue-jest": "^3.0.4",
"vue-template-compiler": "^2.5.22"
"rollup-plugin-vue": "^6.0.0",
"vue": "^3.2.45",
"vue-demi": "0.13.5",
"vue-jest": "^5.0.0-alpha.0",
"vue-jest2": "npm:vue-jest@4",
"vue-template-compiler2.6": "npm:vue-template-compiler@2.6.14",
"vue-template-compiler2.7": "npm:vue-template-compiler@2.7.14",
"vue2": "npm:vue@2.6.14",
"vue2.7": "npm:vue@2.7.14"
},
"lint-staged": {
"*.{js,jsx,json}": [
Expand All @@ -60,25 +77,5 @@
"parserOptions": {
"parser": "babel-eslint"
}
},
"jest": {
"moduleFileExtensions": [
"js",
"jsx",
"json",
"vue"
],
"transform": {
"^.+\\.vue$": "vue-jest",
".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": "jest-transform-stub",
"^.+\\.jsx?$": "babel-jest"
},
"moduleNameMapper": {
"^@/(.*)$": "<rootDir>/src/$1"
},
"snapshotSerializers": [
"jest-serializer-vue"
],
"testURL": "http://localhost/"
}
}
115 changes: 115 additions & 0 deletions packages/simplebar-vue/scripts/swap-vue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* @author Vuelidate <https://github.com/vuelidate/vuelidate/blob/c17ad8927417c71378099c06ec914b4692c4c521/scripts/swap-vue.js>
*/
/* eslint-disable camelcase */
const fs = require('fs');
const path = require('path');

const Vue2 = path.join(__dirname, '../../../node_modules/vue2');
const Vue2_7 = path.join(__dirname, '../../../node_modules/vue2.7');
const DefaultVue = path.join(__dirname, '../../../node_modules/vue');
const Vue3 = path.join(__dirname, '../../../node_modules/vue3');
const vueTemplateCompiler = path.join(
__dirname,
'../../../node_modules/vue-template-compiler'
);
const vueTemplateCompiler2_6 = path.join(
__dirname,
'../../../node_modules/vue-template-compiler2.6'
);
const vueTemplateCompiler2_7 = path.join(
__dirname,
'../../../node_modules/vue-template-compiler2.7'
);

const version = Number(process.argv[2]) || 3;

useVueVersion(version);

function useVueVersion(version) {
console.log('[SWAP-VUE] SETTING VERSION:', version);

if (!fs.existsSync(DefaultVue)) {
console.log('There is no default Vue version, finding it');
if (version === 2 && fs.existsSync(Vue3)) {
rename(Vue3, DefaultVue);
console.log('Renamed "vue3" to "vue"');
} else if (version === 2.7 && fs.existsSync(Vue2_7)) {
rename(Vue2_7, DefaultVue);
useTemplateCompilerVersion(2.7);
console.log('Renamed "vue2.7" to "vue"');
} else {
console.log('ELSE');
rename(Vue2, DefaultVue);
useTemplateCompilerVersion(2);
console.log('Renamed "vue2" to "vue"');
}
}

if (version === 3 && fs.existsSync(Vue3)) {
resetPackageNames();
rename(Vue3, DefaultVue);
} else if (version === 2.7 && fs.existsSync(Vue2_7)) {
resetPackageNames();
rename(Vue2_7, DefaultVue);
useTemplateCompilerVersion(2.7);
} else if (version === 2 && fs.existsSync(Vue2)) {
resetPackageNames();
rename(Vue2, DefaultVue);
useTemplateCompilerVersion(2);
} else {
console.log(`Vue ${version} is already in use`);
}
}

function resetPackageNames() {
if (!fs.existsSync(Vue3)) {
rename(DefaultVue, Vue3);
} else if (!fs.existsSync(Vue2_7)) {
rename(DefaultVue, Vue2_7);
} else if (!fs.existsSync(Vue2)) {
rename(DefaultVue, Vue2);
} else {
console.error('Unable to reset package names');
}
}

function useTemplateCompilerVersion(version) {
if (!fs.existsSync(vueTemplateCompiler)) {
console.log(
'There is no default vue-template-compiler version, finding it',
version
);
if (version === 2.7 && fs.existsSync(vueTemplateCompiler2_7)) {
console.log('VAMOS');
rename(vueTemplateCompiler2_7, vueTemplateCompiler);
console.log(
'Renamed "vue-template-compliler2.7" to "vue-template-compliler"'
);
} else {
rename(vueTemplateCompiler2_6, vueTemplateCompiler);
console.log(
'Renamed "vue-template-compliler2.6" to "vue-template-compliler"'
);
}
}
if (version === 2.7 && fs.existsSync(vueTemplateCompiler2_7)) {
rename(vueTemplateCompiler, vueTemplateCompiler2_6);
rename(vueTemplateCompiler2_7, vueTemplateCompiler);
} else if (version === 2 && fs.existsSync(vueTemplateCompiler2_6)) {
rename(vueTemplateCompiler, vueTemplateCompiler2_7);
rename(vueTemplateCompiler2_6, vueTemplateCompiler);
} else {
console.log(`vue-template-compliler ${version} is already in use`);
}
}

function rename(fromPath, toPath) {
if (!fs.existsSync(fromPath)) return;
try {
fs.renameSync(fromPath, toPath);
console.log(`Successfully renamed ${fromPath} to ${toPath} .`);
} catch (err) {
console.log(err);
}
}
Loading