├── .npmrc
├── .browserslistrc
├── jsconfig.json
├── src
├── scss
│ ├── index.scss
│ ├── _variables.scss
│ ├── _typography.scss
│ └── _base.scss
├── components
│ ├── splitpanes
│ │ ├── index.js
│ │ ├── pane.vue
│ │ └── splitpanes.vue
│ └── highlight-message.vue
├── views
│ ├── example-home-view.vue
│ ├── example-another-view.vue
│ ├── isolated-test-view.vue
│ └── documentation.vue
├── assets
│ └── splitpanes.svg
├── main.js
├── router.js
└── app.vue
├── postcss.config.js
├── docs
├── favicon.png
├── assets
│ ├── _plugin-vue_export-helper-DlAUqK2U.js
│ ├── materialdesignicons-webfont-B7mPwVP_.ttf
│ ├── materialdesignicons-webfont-CSr8KVlo.eot
│ ├── materialdesignicons-webfont-Dp5v-WZN.woff2
│ ├── materialdesignicons-webfont-PXm3-2wK.woff
│ ├── example-home-view-D1_8HrmC.js
│ ├── example-another-view-BueBJawE.js
│ └── isolated-test-view-DcrGDZFU.js
└── index.html
├── .github
└── FUNDING.yml
├── public
└── favicon.png
├── .editorconfig
├── .gitignore
├── eslint.config.js
├── LICENSE
├── index.html
├── vite.config.js
├── package.json
└── README.md
/.npmrc:
--------------------------------------------------------------------------------
1 | strict-peer-dependencies=false
2 |
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 3 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [
3 | "./src/**/*"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/src/scss/index.scss:
--------------------------------------------------------------------------------
1 | @forward './base';
2 | @forward './typography';
3 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export const plugins = {
2 | autoprefixer: {}
3 | }
4 |
--------------------------------------------------------------------------------
/docs/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antoniandre/splitpanes/HEAD/docs/favicon.png
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: antoniandre
4 |
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antoniandre/splitpanes/HEAD/public/favicon.png
--------------------------------------------------------------------------------
/docs/assets/_plugin-vue_export-helper-DlAUqK2U.js:
--------------------------------------------------------------------------------
1 | const s=(t,r)=>{const o=t.__vccOpts||t;for(const[c,e]of r)o[c]=e;return o};export{s as _};
2 |
--------------------------------------------------------------------------------
/src/components/splitpanes/index.js:
--------------------------------------------------------------------------------
1 | import Splitpanes from './splitpanes.vue'
2 | import Pane from './pane.vue'
3 |
4 | export { Splitpanes, Pane }
5 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | trim_trailing_whitespace = true
5 | insert_final_newline = true
6 |
--------------------------------------------------------------------------------
/src/views/example-home-view.vue:
--------------------------------------------------------------------------------
1 |
2 | .green-light5--bg.w-flex.align-center.justify-center
3 | .title1 This is home
4 |
5 |
--------------------------------------------------------------------------------
/docs/assets/materialdesignicons-webfont-B7mPwVP_.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antoniandre/splitpanes/HEAD/docs/assets/materialdesignicons-webfont-B7mPwVP_.ttf
--------------------------------------------------------------------------------
/docs/assets/materialdesignicons-webfont-CSr8KVlo.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antoniandre/splitpanes/HEAD/docs/assets/materialdesignicons-webfont-CSr8KVlo.eot
--------------------------------------------------------------------------------
/docs/assets/materialdesignicons-webfont-Dp5v-WZN.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antoniandre/splitpanes/HEAD/docs/assets/materialdesignicons-webfont-Dp5v-WZN.woff2
--------------------------------------------------------------------------------
/docs/assets/materialdesignicons-webfont-PXm3-2wK.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antoniandre/splitpanes/HEAD/docs/assets/materialdesignicons-webfont-PXm3-2wK.woff
--------------------------------------------------------------------------------
/src/views/example-another-view.vue:
--------------------------------------------------------------------------------
1 |
2 | .blue-light5--bg.w-flex.align-center.justify-center
3 | .title1 This is another view
4 |
5 |
--------------------------------------------------------------------------------
/src/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | $primary: #42b983;
2 | $secondary: #78cfa8;
3 | $main-text: #888;
4 | $dark-text: #666;
5 | $darker-text: #333;
6 | $light-text: #ccc;
7 | $lighter-text: #ddd;
8 | // $light-link: #fff;
9 | $page-max-width: 1150px;
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/docs/assets/example-home-view-D1_8HrmC.js:
--------------------------------------------------------------------------------
1 | import{c as t,a as s,o}from"./index-B9XE5B_l.js";import{_ as r}from"./_plugin-vue_export-helper-DlAUqK2U.js";const n={class:"green-light5--bg w-flex align-center justify-center"};function a(i,e){return o(),t("div",n,e[0]||(e[0]=[s("div",{class:"title1"},"This is home",-1)]))}const c={},f=r(c,[["render",a]]);export{f as default};
2 |
--------------------------------------------------------------------------------
/docs/assets/example-another-view-BueBJawE.js:
--------------------------------------------------------------------------------
1 | import{c as t,a as s,o}from"./index-B9XE5B_l.js";import{_ as r}from"./_plugin-vue_export-helper-DlAUqK2U.js";const n={class:"blue-light5--bg w-flex align-center justify-center"};function a(c,e){return o(),t("div",n,e[0]||(e[0]=[s("div",{class:"title1"},"This is another view",-1)]))}const i={},d=r(i,[["render",a]]);export{d as default};
2 |
--------------------------------------------------------------------------------
/src/assets/splitpanes.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import router from '@/router'
3 | import WaveUI from 'wave-ui'
4 | import 'wave-ui/dist/wave-ui.css'
5 | import App from './app.vue'
6 |
7 | import '@mdi/font/css/materialdesignicons.min.css'
8 |
9 | const app = createApp(App)
10 |
11 | app.use(router)
12 | app.use(WaveUI, {
13 | colors: {
14 | primary: '#42b983',
15 | maintext: '#999',
16 | darktext: '#444',
17 | lightertext: '#ccc',
18 | lightgrey: '#eee'
19 | }
20 | })
21 |
22 | app.mount('#app')
23 |
--------------------------------------------------------------------------------
/src/views/isolated-test-view.vue:
--------------------------------------------------------------------------------
1 |
2 | splitpanes.default-theme(horizontal style="height: 500px")
3 | pane.w-flex.align-center.justify-center(v-for="pane in panes" :size="pane.size")
4 | | {{ pane.content }}
5 |
6 | w-button.ma3(@click="panes.reverse()") Reverse panes order
7 |
8 |
9 |
19 |
20 |
22 |
--------------------------------------------------------------------------------
/docs/assets/isolated-test-view-DcrGDZFU.js:
--------------------------------------------------------------------------------
1 | import{r as _,c as o,b as r,w as n,u as c,_ as f,d as m,F as l,o as s,e as d,f as p,g as z,h as i,t as v}from"./index-B9XE5B_l.js";const k={__name:"isolated-test-view",setup(w){const a=_([{content:"Pane 1 content.",size:30},{content:"Pane 2 content.",size:15},{content:"Pane 3 content.",size:25}]);return(x,e)=>{const u=m("w-button");return s(),o(l,null,[r(c(f),{class:"default-theme",horizontal:"",style:{height:"500px"}},{default:n(()=>[(s(!0),o(l,null,d(a,t=>(s(),p(c(z),{class:"w-flex align-center justify-center",size:t.size},{default:n(()=>[i(v(t.content),1)]),_:2},1032,["size"]))),256))]),_:1}),r(u,{class:"ma3",onClick:e[0]||(e[0]=t=>a.reverse())},{default:n(()=>e[1]||(e[1]=[i("Reverse panes order")])),_:1,__:[1]})],64)}}};export{k as default};
2 |
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import { createRouter, createWebHistory } from 'vue-router'
2 | import Documentation from '@/views/documentation.vue'
3 |
4 | export default createRouter({
5 | history: createWebHistory(import.meta.env.BASE_URL),
6 | routes: [
7 | {
8 | path: '/',
9 | component: Documentation,
10 | children: [
11 | {
12 | path: '/example-home-view',
13 | component: () => import('@/views/example-home-view.vue')
14 | },
15 | {
16 | path: '/example-another-view',
17 | component: () => import('@/views/example-another-view.vue')
18 | }
19 | ]
20 | },
21 | {
22 | path: '/test',
23 | component: () => import('@/views/isolated-test-view.vue')
24 | }
25 | ]
26 | })
27 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import globals from 'globals'
2 | import pluginJs from '@eslint/js'
3 | import pluginVue from 'eslint-plugin-vue'
4 | import importPlugin from 'eslint-plugin-import'
5 | import nPlugin from 'eslint-plugin-n'
6 | import promisePlugin from 'eslint-plugin-promise'
7 | import standard from 'eslint-config-standard'
8 |
9 | export default [
10 | { files: ['**/*.{js,mjs,cjs,vue}'] },
11 | { languageOptions: { globals: { ...globals.browser, ...globals.node } } },
12 | pluginJs.configs.recommended,
13 | {
14 | name: 'standard',
15 | rules: standard.rules,
16 | plugins: {
17 | import: importPlugin,
18 | n: nPlugin,
19 | promise: promisePlugin
20 | }
21 | },
22 | ...pluginVue.configs['flat/essential'],
23 | {
24 | rules: {
25 | 'brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
26 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
27 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
28 | 'vue/multi-word-component-names': 'off'
29 | }
30 | }
31 | ]
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Antoni Andre
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/scss/_typography.scss:
--------------------------------------------------------------------------------
1 | @use './variables' as *;
2 |
3 | body {
4 | font: 15px 'Avenir', Helvetica, Arial, sans-serif;
5 | -webkit-font-smoothing: antialiased;
6 | -moz-osx-font-smoothing: grayscale;
7 | color: rgba(0,0,0,.87);
8 | }
9 |
10 | h1, h2, h3, h4 {
11 | font-weight: 400;
12 | margin-bottom: 0.5em;
13 | }
14 |
15 | h1 {
16 | font-size: 2.6em;
17 | }
18 |
19 | h2 {
20 | font-size: 2.2em;
21 | margin-top: 3em;
22 | color: $primary;
23 | padding-bottom: 0.3em;
24 | border-bottom: 1px solid $lighter-text;
25 |
26 | a {color: inherit;}
27 | }
28 |
29 | h3 {
30 | font-size: 1.6em;
31 | margin-top: 4em;
32 | color: #333;
33 |
34 | a {color: inherit;}
35 | }
36 |
37 | h2 + h3,
38 | h2 + a[id] + h3 {
39 | margin-top: 0;
40 | }
41 |
42 | h3 a[href] {
43 | color: inherit !important;
44 | }
45 |
46 | h3 a[href]:before {
47 | content: "# ";
48 | color: $lighter-text;
49 | font-size: 1.2em;
50 | transition: 0.3s;
51 | }
52 |
53 | h3 a[href]:hover:before {
54 | color: $light-text;
55 | }
56 |
57 | h4 {
58 | margin-top: 2em;
59 | font-size: 1.2em;
60 | color: $dark-text;
61 | }
62 |
63 | a {
64 | text-decoration: none;
65 | }
66 |
67 | p b {
68 | color: $darker-text;
69 | font-weight: 500;
70 | }
71 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Splitpanes
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import Vue from '@vitejs/plugin-vue'
3 | import { resolve } from 'path'
4 | import Delete from 'rollup-plugin-delete'
5 |
6 | const bundleBuild = {
7 | lib: {
8 | entry: resolve(__dirname, '/src/components/splitpanes/index.js'),
9 | name: 'splitpanes',
10 | fileName: 'splitpanes',
11 | formats: ['es', 'umd', 'cjs']
12 | },
13 | rollupOptions: {
14 | plugins: [
15 | // Rollup also copies the files in the public folder.
16 | // @todo: find a way to prevent adding them at all.
17 | Delete({ targets: ['dist/*.{ico,png,html}'], hook: 'generateBundle' })
18 | ],
19 | // Make sure to externalize deps that shouldn't be bundled into library.
20 | external: ['vue'],
21 | output: {
22 | // Provide global variables to use in the UMD build for externalized deps.
23 | globals: { vue: 'Vue' },
24 | entryFileNames: 'splitpanes.[format].js',
25 | chunkFileNames: '[name].js'
26 | }
27 | }
28 | }
29 |
30 | export default defineConfig({
31 | plugins: [
32 | Vue({
33 | template: {
34 | compilerOptions: {
35 | whitespace: 'preserve'
36 | }
37 | }
38 | })
39 | ], // https://vitejs.dev/config/
40 | resolve: {
41 | alias: {
42 | '@': resolve(__dirname, '/src')
43 | }
44 | },
45 | css: {
46 | preprocessorOptions: {
47 | scss: {
48 | api: 'modern-compiler',
49 | additionalData: '@use "@/scss/_variables.scss" as *;'
50 | }
51 | }
52 | },
53 | build: process.env.BUNDLE ? bundleBuild : { outDir: 'docs' },
54 | define: {
55 | __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
56 | }
57 | })
58 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Splitpanes
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/components/highlight-message.vue:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 | component(:class="`highlight highlight--${type}`" :is="tag")
24 | w-icon(v-if="!noIcon") {{ icon }}
25 | slot
26 |
27 |
28 |
80 |
--------------------------------------------------------------------------------
/src/components/splitpanes/pane.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
64 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "splitpanes",
3 | "version": "4.0.4",
4 | "description": "A Vue.js reliable, simple and touch-ready panes splitter / resizer",
5 | "author": "Antoni Andre ",
6 | "homepage": "https://antoniandre.github.io/splitpanes",
7 | "repository": "https://github.com/antoniandre/splitpanes",
8 | "license": "MIT",
9 | "funding": "https://github.com/sponsors/antoniandre",
10 | "main": "./dist/splitpanes.es.js",
11 | "unpkg": "dist/splitpanes.umd.js",
12 | "jsdelivr": "dist/splitpanes.umd.js",
13 | "module": "./dist/splitpanes.es.js",
14 | "files": [
15 | "dist",
16 | "src/components/splitpanes"
17 | ],
18 | "exports": {
19 | ".": {
20 | "import": "./dist/splitpanes.es.js",
21 | "require": "./dist/splitpanes.umd.js"
22 | },
23 | "./package.json": "./package.json",
24 | "./dist/*": "./dist/*"
25 | },
26 | "type": "module",
27 | "keywords": [
28 | "splitpanes",
29 | "split panes",
30 | "panes resizer",
31 | "vue",
32 | "vue3",
33 | "vuejs",
34 | "ui"
35 | ],
36 | "scripts": {
37 | "dev": "vite",
38 | "build": "vite build --base /splitpanes/",
39 | "build-bundle": "BUNDLE=true vite build",
40 | "serve": "vite preview --base /splitpanes/",
41 | "publish-doc": "npm run build && npm run build-bundle && git add . && git commit -m 'Publish documentation on Github.' && git push && git push --tag"
42 | },
43 | "devDependencies": {
44 | "@eslint/js": "^9.27.0",
45 | "@mdi/font": "^7.4.47",
46 | "@vitejs/plugin-vue": "^5.2.4",
47 | "autoprefixer": "^10.4.21",
48 | "eslint": "^9.27.0",
49 | "eslint-config-standard": "^17.1.0",
50 | "eslint-plugin-import": "^2.31.0",
51 | "eslint-plugin-n": "^17.18.0",
52 | "eslint-plugin-promise": "^7.2.1",
53 | "eslint-plugin-vue": "^9.33.0",
54 | "globals": "^16.1.0",
55 | "postcss": "^8.5.3",
56 | "pug": "^3.0.3",
57 | "rollup-plugin-delete": "^3.0.1",
58 | "sass": "^1.89.0",
59 | "simple-syntax-highlighter": "^3.1.1",
60 | "vite": "^6.3.5",
61 | "vue": "^3.5.14",
62 | "vue-router": "^4.5.1",
63 | "wave-ui": "^3.21.1"
64 | },
65 | "peerDependencies": {
66 | "vue": "^3.2.0"
67 | },
68 | "packageManager": "pnpm@10.0.0"
69 | }
70 |
--------------------------------------------------------------------------------
/src/app.vue:
--------------------------------------------------------------------------------
1 |
27 |
28 |
29 | div(v-scroll="onScroll")
30 | router-view
31 |
32 | w-transition-twist
33 | w-button.go-top(
34 | v-show="!goTopHidden"
35 | icon="wi-chevron-up"
36 | fixed
37 | bottom
38 | right
39 | round
40 | @click="scrollToTop")
41 |
42 | footer.py2(color="white")
43 | w-flex.page-container(wrap justify-center)
44 | .xs12.sm6.text-center.smu-text-left.copyright.
45 | Copyright © {{ (new Date()).getFullYear() }} Antoni André, all rights reserved.
46 | .xs12.sm6.text-center.smu-text-right.made-with
47 | .mb1
48 | | This documentation is made with
49 | w-tooltip(top caption)
50 | template(#activator="{ on }")
51 | w-icon.ml1(v-on="on") mdi mdi-vuejs
52 | | Vue.js
53 | w-tooltip(top caption)
54 | template(#activator="{ on }")
55 | w-icon.ml1(v-on="on" size="1.5em") wi-wave
56 | | Wave UI
57 | w-tooltip(top caption)
58 | template(#activator="{ on }")
59 | w-icon.ml1(v-on="on") mdi mdi-language-html5
60 | | HTML 5
61 | w-tooltip(top caption)
62 | template(#activator="{ on }")
63 | w-icon.ml1(v-on="on") mdi mdi-language-css3
64 | | CSS 3
65 | w-tooltip(top caption)
66 | template(#activator="{ on }")
67 | w-icon.ml1(v-on="on") mdi mdi-sass
68 | | SASS
69 | span.ml1 &
70 | w-tooltip(top caption)
71 | template(#activator="{ on }")
72 | w-icon.ml1(v-on="on").heart mdi mdi-heart
73 | | Love
74 | | View this project on #[a(href="https://github.com/antoniandre/splitpanes" target="_blank") #[w-icon mdi mdi-github] Github].
75 |
76 |
--------------------------------------------------------------------------------
/src/scss/_base.scss:
--------------------------------------------------------------------------------
1 | @use './variables' as *;
2 |
3 | // Global.
4 | // --------------------------------------------------------
5 | * {
6 | margin: 0;
7 | padding: 0;
8 | }
9 |
10 | body {
11 | padding-top: 7em;
12 | }
13 |
14 | a {
15 | text-decoration: none;
16 | color: $primary;
17 | }
18 |
19 | ul, ol {
20 | margin-top: 1em;
21 | padding-left: 1.3em;
22 | }
23 |
24 | p {margin-bottom: 16px;}
25 |
26 | code, .code:not(.w-icon) {
27 | font-family: monospace, sans-serif;
28 | font-size: 0.9em;
29 | }
30 |
31 | code {
32 | padding: .15em .4em;
33 | background-color: rgba(0,0,0,.05);
34 | color: #dc163c;
35 | border-radius: 4px;
36 | }
37 |
38 | .ssh-pre {
39 | padding: 0.5em;
40 | margin: 1.5em 0;
41 | border: 1px solid $lighter-text;
42 | background-color: #f8f8f8;
43 | border-radius: 4px;
44 | display: block;
45 | box-shadow: none;
46 | font-size: 0.9em;
47 | line-height: 1.4;
48 | }
49 |
50 | .page__title {
51 | color: $primary;
52 | background-color: #fff;
53 | padding: 1.5em;
54 | display: inline-flex;
55 | align-items: center;
56 | }
57 |
58 | .w-button {
59 | text-transform: uppercase;
60 | font-weight: 500;
61 |
62 | &.size--md:not(.w-button--round) {
63 | height: 28px;
64 | padding-left: 12px;
65 | padding-right: 12px;
66 | }
67 | }
68 |
69 | .pale-blue {color: #1471b8;}
70 |
71 | // Application.
72 | // --------------------------------------------------------
73 | .w-app {
74 | overflow-x: hidden;
75 | }
76 |
77 | .page-container {
78 | flex-grow: 1;
79 | max-width: $page-max-width;
80 | margin-left: auto;
81 | margin-right: auto;
82 | }
83 |
84 | header {margin-bottom: 6em;}
85 |
86 | .w-tag i.w-icon {
87 | position: relative;
88 | color: rgba(0, 0, 0, .25);
89 | margin: 0 7px 0 -7px;
90 | }
91 |
92 | .settings-list {
93 | li {padding: 20px 10px;}
94 |
95 | li li {
96 | padding-top: 0;
97 | padding-bottom: 0;
98 | margin-left: 10px;
99 | margin-top: 10px;
100 | }
101 |
102 | code {
103 | font-size: 0.95em;
104 | display: inline-flex;
105 | margin-bottom: 4px;
106 | }
107 | }
108 |
109 | .w-app .go-top {
110 | width: 1.8em;
111 | height: 1.8em;
112 | font-size: 1.5em;
113 | box-shadow: 0 3px 5px -1px rgb(0 0 0 / 20%), 0 6px 10px 0 rgb(0 0 0 / 14%), 0 1px 18px 0 rgb(0 0 0 / 12%);
114 | }
115 |
116 | // Footer.
117 | // --------------------------------------------------------
118 | footer {
119 | background: none;
120 | font-style: italic;
121 | color: $main-text;
122 | font-size: 0.9em;
123 | margin: 5em 0 3.5em;
124 |
125 | i {
126 | font-size: 1.2em;
127 | vertical-align: text-bottom;
128 | transition: 1s ease-out;
129 | cursor: pointer;
130 |
131 | &.heart:hover {animation: pulse 1.8s ease-out infinite;}
132 | }
133 | }
134 |
135 | // Animations.
136 | // --------------------------------------------------------
137 | @keyframes pulse {
138 | 0%, 20%, 30%, 35%, 45%, 100% {transform: scale(1);}
139 | 25%, 40% {transform: scale(1.3);}
140 | }
141 |
142 | .pulse {animation: pulse 1.5s infinite;}
143 |
144 | // Media queries.
145 | // --------------------------------------------------------
146 | @media screen and (max-width: ($page-max-width + 20px)) {
147 | .page-container {
148 | margin-left: 10px;
149 | margin-right: 10px;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Splitpanes
2 |
3 | [](https://npmjs.com/package/splitpanes)
4 | [](LICENSE.md)
5 | [](https://www.npmjs.com/package/splitpanes)
6 | [](https://www.npmjs.com/package/splitpanes)
7 | [](https://standardjs.com)
8 |
9 | > A Vue.js reliable, simple and touch-ready panes splitter / resizer.
10 | > Vue 3 compatible.
11 |
12 | ## Installation
13 |
14 | **Vue 3**
15 |
16 | ```
17 | npm i splitpanes
18 | ```
19 |
20 | **Vue 2**
21 |
22 | ```
23 | npm i splitpanes@legacy
24 | ```
25 |
26 | ---
27 |
28 | ## Demo & Documentation
29 | > [https://antoniandre.github.io/splitpanes](https://antoniandre.github.io/splitpanes)
30 |
31 | ## Try it yourself
32 | > [https://codepen.io/antoniandre/pen/XybPKP](https://codepen.io/antoniandre/pen/XybPKP)
33 |
34 | ---
35 |
36 | ## Browser Support
37 |  |  |  |  |  |  |
38 | --- | --- | --- | --- | --- | --- |
39 | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | 10+ ✔ |
40 |
41 | ___
42 |
43 | ## Donating
44 |
45 | If you like this library, you can buy me a beer or [become a sponsor](https://github.com/sponsors/antoniandre)!
46 |
47 | [](https://www.paypal.me/antoniandre1)
48 | Thank you!
49 |
50 | If you are using this library for profit business, please consider [backing me](https://github.com/sponsors/antoniandre)!
51 | It ensures that the project your products rely on keeps being actively maintained. :)
52 |
53 | ___
54 |
55 | ## Contributing
56 |
57 | If you have any idea, feel free to open an issue to discuss a new feature, or fork Splitpanes and submit your changes back to me.
58 |
59 | ___
60 |
61 | ## Release Notes
62 |
63 | - __Version 2.3.0__ Support rtl direction
64 | - __Version 2.2.0__ Add `firstSplitter` option allow `v-if` on panes and other improvements
65 | - __Version 2.0.0__ Fix reactivity issues
66 | - __Version 1.14.0__ Programmatically set pane size
67 | - __Version 1.13.0__ Emit event on splitter click
68 | - __Version 1.12.0__ Double click splitter to maximize is now an option
69 | - __Version 1.11.0__ Persist panes size after slots changed
70 | - __Version 1.10.0__ Add maximum size feature on panes
71 | - __Version 1.9.0__ Emit event on resize & watch slots optional
72 | - __Version 1.8.0__ Watch slots
73 | - __Version 1.7.0__ Double click splitter to maximize next pane
74 | - __Version 1.6.0__ Emit events
75 | - __Version 1.5.0__ Add default size feature on panes (max feature coming soon!)
76 | - __Version 1.4.0__ Add minimum size feature on panes
77 | - __Version 1.3.0__ Splitpanes slots are now reactive (add/remove on the fly)
78 | - __Version 1.2.0__ Add a `default-theme` CSS class to load default theme
79 | - __Version 1.1.0__ Allow pushing other panes while dragging splitter
80 | - __Version 1.0.0__ First public release
81 |
--------------------------------------------------------------------------------
/src/components/splitpanes/splitpanes.vue:
--------------------------------------------------------------------------------
1 |
686 |
687 |
688 |
689 |
690 |
691 |
774 |
--------------------------------------------------------------------------------
/src/views/documentation.vue:
--------------------------------------------------------------------------------
1 |
2 | .page-container
3 | header.text-center
4 | svg.mb5(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" xml:space="preserve" width="4em")
5 | path(d="M469 500v490h57V10h-57v490z" fill="#42b983")
6 | path(d="m109 417-83 83 80 80 81 81 20-20 20-20-46-46-46-46h219v-58H135l48-47 49-49c0-2-9-11-20-22l-20-20-83 84z" fill="#35495e")
7 | path(d="m789 354-21 20 11 11 46 48 35 37-109 1H641v58h219l-46 46-46 46 21 20 20 20 82-83 83-83-13-11-82-81-70-70-20 21z" fill="#35495e")
8 | h1.mb3.title1 Splitpanes
9 |
10 | p.grey A Vue.js reliable, simple and touch-ready panes splitter / resizer.
11 |
12 | h2.mt12.mb2.title2 Features
13 | ul.checklist
14 | li
15 | w-icon.mr2(color="primary" size="20") wi-check
16 | | Light weight & no dependencies other than Vue JS
17 | li
18 | w-icon.mr2(color="primary" size="20") wi-check
19 | | Only worry about your panes, the splitters are automatic
20 | li
21 | w-icon.mr2(color="primary" size="20") wi-check
22 | | Nesting supported
23 | li
24 | w-icon.mr2(color="primary" size="20") wi-check
25 | | Fully responsive
26 | li
27 | w-icon.mr2(color="primary" size="20") wi-check
28 | | Support for touch devices
29 | li
30 | w-icon.mr2(color="primary" size="20") wi-check
31 | | Push other panes or not
32 | li
33 | w-icon.mr2(color="primary" size="20") wi-check
34 | | Double click a splitter to maximize pane
35 | li
36 | w-icon.mr2(color="primary" size="20") wi-check
37 | | Programmatically set pane width or height
38 | li
39 | w-icon.mr2(color="primary" size="20") wi-check
40 | | Programmatically add and remove panes
41 | li
42 | w-icon.mr2(color="primary" size="20") wi-check
43 | | Also supports Vue 2 (legacy branch)
44 |
45 | h2.mt12.mb4.title2 Github project & important notes
46 | w-flex(align-center shrink)
47 | w-icon.ml1.mr5.lightgrey(size="46") mdi mdi-github
48 | a(href="https://github.com/antoniandre/splitpanes" target="_blank") //github.com/antoniandre/splitpanes #[w-icon(color="primary") mdi mdi-open-in-new]
49 |
50 | w-flex.my4(align-center)
51 | w-icon.mr4(size="50" color="pink-light3") mdi mdi-heart
52 | w-alert.ma0(border-left color="pink" style="width: 100%;max-width: 600px")
53 | | If you like Splitpanes, you can
54 | a.pink.mx2(
55 | href="https://www.paypal.me/antoniandre1"
56 | target="_blank"
57 | style="text-decoration: underline") #[strong Support the project]
58 | | or
59 | a.pink.ml2(
60 | href="https://github.com/sponsors/antoniandre"
61 | target="_blank"
62 | style="text-decoration: underline") #[strong Sponsor the author]
63 | | !
64 | div Thank you so much to all the backers! #[span.title2.ml1 🙏]
65 |
66 | .w-flex.mb8.align-center
67 | svg.mr4.blue-light1(viewBox="0 0 725 477" style="width: 50px;stroke: #497ca2;stroke-width: 5px")
68 | path(fill="#497ca2" d="M449 0c-78 5-152 39-217 82-19 13-37 26-54 40-39 1-77 15-110 34-34 21-53 60-61 99-11 52-8 108 6 159 7 23 16 46 33 63 4-4 13-4 13-11-1-5-7-8-9-14-27-48-32-108-11-159 13-32 36-63 68-77 19-9 42-7 58 6 6 7 18 4 24-2 6-4 11-10 19-10-24 25-39 60-38 95 1 15 3 31 8 45 16 36 41 69 76 89 5 2 10 6 16 7 5-2 14-5 14-12-4-9-14-12-21-18-27-23-56-48-67-82-9-29-1-60 8-88 7-15 21-32 39-29 15 1 28 13 43 8 11-5 13-17 16-27 5-17 3-38-10-51-16-18-40-23-62-25l-11-2c23-19 53-26 81-31 21-3 43-5 64-2 18 3 28 21 42 31-33 47-57 102-56 159a170 170 0 0086 149c6-1 13-7 10-14-5-11-17-16-25-25-33-30-52-75-50-121 1-29 11-58 24-84 12-25 25-52 47-71 9-8 22-13 33-7 20 8 42 14 63 13-35 27-55 70-64 113-9 44-7 91 12 133 15 37 45 68 81 85 32 16 67 24 101 27 18 1 36 2 53-4 4-1 6-7 2-9-13-6-28-4-42-6-45-5-92-16-127-45-34-28-54-71-60-114-5-47 7-97 34-137 11-15 26-31 45-34 14-1 25 12 31 23 6 12 16 24 29 28 20-10 40-26 43-50 2-17-6-34-14-49-15-25-40-43-69-48-20-5-41-2-61-6-22-21-54-24-83-24zm6 21c22 0 48 5 62 25 4 7 8 16 8 24-1 10-10 22-21 19-9-7-18-14-30-16-14-4-31-1-43 8-6 6-17 8-24 2-9-6-17-15-28-17-27-7-54 1-81 6a364 364 0 01157-51zm117 29c33 0 66 25 72 58 3 12 3 28-8 35-3 2-6 4-8 1-8-12-12-27-23-37-3-7-12-8-19-9-13-2-26 0-39-4 7-7 6-17 4-25l-3-16 24-3zm-372 92l46 2c18 2 33 16 34 34 1 7 1 17-6 21-6 0-12-4-18-6-21-8-46-14-67-3-6 2-11 9-17 5-10-4-18-14-30-12-30 1-56 21-77 42-16 17-30 37-43 56 0-39 17-80 49-104 26-22 61-30 94-34l35-1z")
69 | w-alert.ma0(border-left color="pale-blue" style="width: 100%;max-width: 600px")
70 | .text-bold
71 | | Do you need A UI framework? Checkout
72 | a.title2.ml4(
73 | href="https://antoniandre.github.io/wave-ui"
74 | target="_blank"
75 | style="width: 50px;color: #1471b8;text-decoration: underline")
76 | strong Wave UI
77 | div By the same awesome author.
78 |
79 | .title4.mt12.pt12.mb2
80 | | # Demo -
81 | a.ml1.d-inline-flex.align-center(href="https://codepen.io/antoniandre/pen/XybPKP" target="_blank")
82 | | try it yourself on Codepen
83 | w-icon.ml1(color="primary") mdi mdi-open-in-new
84 |
85 | splitpanes.default-theme.example.example1(style="height: 400px")
86 | pane(min-size="20")
87 | span 1#[br]#[em.specs I have a min width of 20%]
88 | pane
89 | splitpanes.default-theme.example(horizontal)
90 | pane
91 | span 2
92 | pane
93 | span 3
94 | pane
95 | span 4
96 | pane
97 | span 5
98 |
99 | w-flex.pb6(wrap)
100 | ssh-pre.grow.mb0.mr2(language="html-vue" label="HTML Vue Template").
101 | <splitpanes style="height: 400px">
102 | <pane min-size="20">1</pane>
103 | <pane>
104 | <splitpanes horizontal>
105 | <pane>2</pane>
106 | <pane>3</pane>
107 | <pane>4</pane>
108 | </splitpanes>
109 | </pane>
110 | <pane>5</pane>
111 | </splitpanes>
112 | ssh-pre.grow.mb0(language="css" label="CSS").
113 | .splitpanes__pane {
114 | display: flex;
115 | justify-content: center;
116 | align-items: center;
117 | font-family: Helvetica, Arial, sans-serif;
118 | color: rgba(255, 255, 255, 0.6);
119 | font-size: 5em;
120 | }
121 |
122 | h2.mt12.mb2(id="installation")
123 | a(href="#installation") Installation
124 |
125 | p You have two options: #[em NPM] #[strong.mx1 or] #[span.code <script>] tag.
126 | h3.mt12 Via NPM
127 |
128 | w-flex(align-center wrap)
129 | ssh-pre.px4(language="shell").
130 | npm i splitpanes # For Vue 3
131 | span.mx2 or
132 | ssh-pre.px4(language="shell").
133 | npm i splitpanes@legacy # For Vue 2
134 |
135 | p.mt2
136 | w-icon.mr1 wi-chevron-right
137 | | View and edit a working
138 | a.ml2(href="https://codepen.io/antoniandre/pen/LYNKGWV" target="_blank") Vue 3 example
139 | | , or
140 | a.mx2(href="https://codepen.io/antoniandre/pen/XybPKP" target="_blank") Vue 2 example
141 | | on Codepen.
142 |
143 | .mt6 Then import the component and CSS:
144 | w-tabs(:items="2" content-class="pa0")
145 | template(#item-title.1) Composition API
146 | template(#item-content.1)
147 | ssh-pre.ma0.bd0(language="js").
148 | import { Splitpanes, Pane } from 'splitpanes'
149 | import 'splitpanes/dist/splitpanes.css'
150 | template(#item-title.2) Options API
151 | template(#item-content.2)
152 | ssh-pre.ma0.bd0(language="js").
153 | import { Splitpanes, Pane } from 'splitpanes'
154 | import 'splitpanes/dist/splitpanes.css'
155 |
156 | export default {
157 | components: { Splitpanes, Pane },
158 | ...
159 | }
160 |
161 | h3.mt12 Via #[span.code <script>] tag
162 | p Include the Splitpanes script in your document #[span.code <head>] as follows:
163 | ssh-pre(language="html" label="HTML").
164 | <head>
165 | ...
166 | <script src="https://unpkg.com/vue"></script>
167 | <script src="https://unpkg.com/splitpanes"></script>
168 | <link href="https://unpkg.com/splitpanes/dist/splitpanes.css" rel="stylesheet">
169 | </head>
170 |
171 | h2.mt12.mb2(id="how-to-use")
172 | a(href="#how-to-use") How to use
173 |
174 | p.
175 | Once included in your project, use as follows.
176 |
177 | ssh-pre(language="html-vue" label="HTML Vue Template").
178 | <splitpanes class="default-theme">
179 | <pane v-for="i in 3" :key="i">
180 | <div>{{ '\{\{ i \}\}' }}</div>
181 | </pane>
182 | </splitpanes>
183 |
184 | highlight-message(type="success")
185 | strong No splitter tags!#[br]
186 | span The splitters will be added automatically between the #[span.code <pane>] tags.
187 |
188 | highlight-message(type="tips").
189 | By default the layout is vertical, if you need you can set the attribute
190 | #[span.code horizontal] on the #[span.code <splitpanes>] tag to change the layout to rows.
191 |
192 | highlight-message(type="tips").
193 | The CSS is external so you can easily override or choose not to include it at all.#[br]
194 | If you want to use it, you can also optionally use the CSS class #[span.code default-theme]
195 | at the root of your splitpanes to apply the default theme like on this page.#[br]
196 | If you want to go with your own style, you can check the #[a(href="#do-your-own-style") Do Your Own Style example].
197 |
198 | //- Examples.
199 | //-------------------------------------------------------//
200 | h2.mt12.mb2(id="more-examples")
201 | a(href="#more-examples") More examples
202 |
203 | //- Example.
204 | h3.mt10.mb2(id="horizontal-layout")
205 | a(href="#horizontal-layout") Horizontal layout, push other panes, min & max use
206 | p By default, you can also double click a splitter to maximize the next pane (displaying the first pane splitter is an option).
207 | p But if you want to disable this feature, you can set: #[span.code :maximize-panes="false"].
208 | splitpanes.default-theme.example(horizontal style="height: 400px")
209 | pane(min-size="20", max-size="70")
210 | span 1#[br]#[em.specs I have a min height of 20% & max height of 70%]
211 | pane
212 | span 2
213 | pane(max-size="70")
214 | span 3#[br]#[em.specs I have a max height of 70%]
215 |
216 | ssh-pre(language="html-vue" label="HTML").
217 | <splitpanes class="default-theme" horizontal style="height: 400px">
218 | <pane min-size="20" max-size="70">
219 | <span>1</span>
220 | </pane>
221 | <pane>
222 | <span>2</span>
223 | </pane>
224 | <pane max-size="70">
225 | <span>3</span>
226 | </pane>
227 | </splitpanes>
228 |
229 | //- Example.
230 | h3.mt12.pt8.mb2(id="ex--default-pane-width")
231 | a(href="#ex--default-pane-width") Default pane width or height
232 | p
233 | | Provide dimension of your panes when they first load (will be used for the width or height respectively for the vertical or horizontal layout).#[br]
234 | strong.
235 | If you provide a default width or height, make sure you provide it for all the panes and the total equals 100%.#[br]
236 | If a pane is missing a default width or height, then all the panes will have the same width or height.#[br]
237 | | Note that setting a default value is different than setting a min or max value.
238 |
239 | splitpanes.default-theme.example(horizontal style="height: 400px")
240 | pane(size="65")
241 | span 1
242 | pane(size="10")
243 | span 2
244 | pane(size="25")
245 | span 3
246 |
247 | ssh-pre(language="html-vue" label="HTML").
248 | <splitpanes class="default-theme" horizontal style="height: 400px">
249 | <pane size="65">
250 | <span>1</span>
251 | </pane>
252 | <pane size="10">
253 | <span>2</span>
254 | </pane>
255 | <pane size="25">
256 | <span>3</span>
257 | </pane>
258 | </splitpanes>
259 |
260 | //- Example.
261 | h3.mt12.pt8.mb2(id="ex--nested-splitpanes")
262 | a(href="#ex--nested-splitpanes") Mix layout with nested splitpanes & prevent pushing other panes
263 | p
264 | a(href="https://codepen.io/antoniandre/pen/PypgKY" target="_blank")
265 | | Try it yourself on Codepen
266 | w-icon.ml1(color="primary") mdi mdi-open-in-new
267 | splitpanes.default-theme.example(horizontal :push-other-panes="false" style="height: 400px")
268 | pane
269 | span 1
270 | pane
271 | splitpanes(:push-other-panes="false")
272 | pane
273 | span 2
274 | pane
275 | span 3
276 | pane
277 | span 4
278 | pane
279 | span 5
280 |
281 | ssh-pre(language="html-vue" label="HTML").
282 | <splitpanes class="default-theme" horizontal :push-other-panes="false" style="height: 400px">
283 | <pane>
284 | <span>1</span>
285 | </pane>
286 | <pane>
287 | <splitpanes :push-other-panes="false">
288 | <pane>
289 | <span>2</span>
290 | </pane>
291 | <pane>
292 | <span>3</span>
293 | </pane>
294 | <pane>
295 | <span>4</span>
296 | </pane>
297 | </splitpanes>
298 | </pane>
299 | <pane>
300 | <span>5</span>
301 | </pane>
302 | </splitpanes>
303 |
304 | //- Example.
305 | h3.mt12.pt8.mb2(id="ex--lots-of-splitters")
306 | a(href="#ex--lots-of-splitters") Lots of splitters & push other panes - all the panes have a min width of 5%
307 | splitpanes.default-theme.example(style="height: 400px")
308 | pane(v-for="i in 8" :key="i" :min-size="5")
309 | span {{ i }}
310 |
311 | ssh-pre(language="html-vue" label="HTML").
312 | <splitpanes class="default-theme" style="height: 400px">
313 | <pane v-for="i in 8" :key="i" min-size="5">
314 | <span>{{ '\{\{ i \}\}' }}</span>
315 | </pane>
316 | </splitpanes>
317 |
318 | //- Example.
319 | h3.mt12.pt8.mb2(id="ex--adding-splitters-on-the-fly")
320 | a(href="#ex--adding-splitters-on-the-fly") Adding splitters on the fly
321 | p
322 | | This example shows the reactivity when you add a new element dynamically in splitpanes.
323 | w-button.ml2(@click="panesNumber++")
324 | w-icon.mr1 mdi mdi-plus
325 | | Add pane
326 | w-button.ml2(@click="panesNumber--")
327 | w-icon.mr1 mdi mdi-minus
328 | | Remove pane
329 |
330 | splitpanes.default-theme.example(style="height: 400px")
331 | pane(v-for="i in panesNumberAbs" :key="i")
332 | span {{ i }}
333 |
334 | ssh-pre(language="html-vue" label="HTML").
335 | <button @click="panesNumber++">Add pane</button>
336 | <button @click="panesNumber--">Remove pane</button>
337 |
338 | <splitpanes class="default-theme" style="height: 400px">
339 | <pane v-for="i in panesNumber" :key="i">
340 | <span>{{ '\{\{ i \}\}' }}</span>
341 | </pane>
342 | </splitpanes>
343 |
344 | w-tabs(:items="2" content-class="pa0")
345 | template(#item-title.1) Composition API
346 | template(#item-content.1)
347 | ssh-pre.ma0.bd0(language="js").
348 | import { ref } from 'vue'
349 | import { Splitpanes, Pane } from 'splitpanes'
350 | import 'splitpanes/dist/splitpanes.css'
351 |
352 | const panesNumber = ref(3)
353 | template(#item-title.2) Options API
354 | template(#item-content.2)
355 | ssh-pre.ma0.bd0(language="js").
356 | import { Splitpanes, Pane } from 'splitpanes'
357 | import 'splitpanes/dist/splitpanes.css'
358 |
359 | export default {
360 | components: { Splitpanes, Pane },
361 | data: () => ({
362 | panesNumber: 3
363 | }),
364 | ...
365 | }
366 |
367 | //- Example.
368 | h3.mt12.pt8.mb2(id="ex--change-direction")
369 | a(href="#ex--change-direction") Change direction & first splitter
370 | p When changing direction, all the panes current width or height will flip to adapt to the new layout.
371 | p.
372 | Showing the first splitter is an option which allows user to double click the splitter to maximize the next pane.#[br]
373 | The first splitter does not allow to resize the next pane.
374 |
375 | w-button.mr2.mb2(@click="horizontal = !horizontal")
376 | w-icon.ml-n1.mr1 mdi mdi-{{ horizontal ? 'view-column' : 'view-stream' }}
377 | | Switch to {{ horizontal ? 'Vertical' : 'Horizontal' }}
378 | w-button.mr2.mb2(@click="firstSplitter = !firstSplitter")
379 | w-icon.ml-n1.mr1 wi-{{ firstSplitter ? 'cross' : 'plus' }}
380 | | {{ firstSplitter ? 'Hide' : 'Show' }} First Splitter
381 | splitpanes.default-theme.example(
382 | :horizontal="horizontal"
383 | :first-splitter="firstSplitter"
384 | style="height: 400px")
385 | pane(v-for="i in 3" :key="i")
386 | span {{ i }}
387 |
388 | ssh-pre(language="html-vue" label="HTML").
389 | <button @click="horizontal = !horizontal">Switch to {{ "\{\{ horizontal ? 'Vertical' : 'Horizontal' \}\}" }}</button>
390 | <button @click="firstSplitter = !firstSplitter">{{ "\{\{ firstSplitter ? 'Hide' : 'Show' \}\}" }} First Splitter</button>
391 |
392 | <splitpanes class="default-theme" :horizontal="horizontal" :first-splitter="firstSplitter" style="height: 400px">
393 | <pane v-for="i in 3" :key="i">
394 | <span>{{ '\{\{ i \}\}' }}%</span>
395 | </pane>
396 | </splitpanes>
397 |
398 | w-tabs(:items="2" content-class="pa0")
399 | template(#item-title.1) Composition API
400 | template(#item-content.1)
401 | ssh-pre.ma0.bd0(language="js").
402 | import { ref } from 'vue'
403 | import { Splitpanes, Pane } from 'splitpanes'
404 | import 'splitpanes/dist/splitpanes.css'
405 |
406 | const horizontal = ref(false)
407 | const firstSplitter = ref(false)
408 | template(#item-title.2) Options API
409 | template(#item-content.2)
410 | ssh-pre.ma0.bd0(language="js").
411 | import { Splitpanes, Pane } from 'splitpanes'
412 | import 'splitpanes/dist/splitpanes.css'
413 |
414 | export default {
415 | components: { Splitpanes, Pane },
416 | data: () => ({
417 | horizontal: false
418 | firstSplitter: false
419 | }),
420 | ...
421 | }
422 |
423 | //- Example.
424 | h3.mt12.pt8.mb2(id="ex--programmatic-resizing")
425 | a(href="#ex--programmatic-resizing") Programmatic resizing
426 | p.mb6 This example shows the programmatic way of resizing panes and how it works both ways.
427 | p.mt0.mb6.
428 | In this example, the default transition on the .splitpanes__pane element is removed
429 | so it looks fast and reactive.
430 |
431 | w-slider.mt12.mb10(
432 | v-model="paneSize"
433 | track-color="grey-light2"
434 | label="First pane size"
435 | thumb-label="always"
436 | thumb-size="25"
437 | :min="0"
438 | :max="100")
439 | splitpanes.default-theme.example.example--programmatic-resizing(
440 | @resize="({ prevPane }) => paneSize = prevPane.size"
441 | style="height: 400px")
442 | pane(:size="paneSize")
443 | span {{ ~~(paneSize * 100) / 100 }}%
444 | pane(:size="100 - paneSize")
445 | span {{ ~~((100 - paneSize) * 100) / 100 }}%
446 |
447 | ssh-pre(language="html-vue" label="HTML").
448 | <w-slider v-model="paneSize" label="First pane size" :min="0" :max="100">
449 | <splitpanes
450 | class="default-theme"
451 | @resize="({ prevPane }) => paneSize = prevPane.size"
452 | style="height: 400px">
453 | <pane :size="paneSize">
454 | <span>{{ '\{\{ paneSize \}\}' }}%</span>
455 | </pane>
456 | <pane :size="100 - paneSize">
457 | <span>{{ '\{\{ 100 - paneSize \}\}' }}%</span>
458 | </pane>
459 | </splitpanes>
460 |
461 | w-tabs(:items="2" content-class="pa0")
462 | template(#item-title.1) Composition API
463 | template(#item-content.1)
464 | ssh-pre.ma0.bd0(language="js").
465 | import { ref } from 'vue'
466 | import { Splitpanes, Pane } from 'splitpanes'
467 | import 'splitpanes/dist/splitpanes.css'
468 |
469 | const paneSize = ref(50)
470 | template(#item-title.2) Options API
471 | template(#item-content.2)
472 | ssh-pre.ma0.bd0(language="js").
473 | import { Splitpanes, Pane } from 'splitpanes'
474 | import 'splitpanes/dist/splitpanes.css'
475 |
476 | export default {
477 | components: { Splitpanes, Pane },
478 | data: () => ({
479 | paneSize: 50
480 | }),
481 | ...
482 | }
483 |
484 | //- Example.
485 | h3.mt12.pt8.mb2(id="ex--persistent-size")
486 | a(href="#ex--persistent-size") Persistent size after page reload
487 | p This example shows how to maintain and restore the size of the panes after a page reload.
488 | w-button.mb2(@click="reloadPage")
489 |
490 | w-icon.mr1 mdi mdi-refresh
491 | | Reload the page
492 | splitpanes.default-theme.example.example--persistent-size(
493 | @resize="({ prevPane }) => persistentPaneSize = prevPane.size"
494 | @resized="storePaneSize"
495 | style="height: 400px")
496 | pane(:size="persistentPaneSize")
497 | span {{ ~~(persistentPaneSize * 100) / 100 }}%
498 | pane(:size="100 - persistentPaneSize")
499 | span {{ ~~((100 - persistentPaneSize) * 100) / 100 }}%
500 |
501 | ssh-pre(language="html-vue" label="HTML").
502 | <w-slider v-model="paneSize" label="First pane size" :min="0" :max="100">
503 | <splitpanes
504 | class="default-theme"
505 | @resized="storePaneSize"
506 | style="height: 400px">
507 | <pane :size="paneSize">
508 | <span>{{ '\{\{ paneSize \}\}' }}%</span>
509 | </pane>
510 | <pane :size="100 - paneSize">
511 | <span>{{ '\{\{ 100 - paneSize \}\}' }}%</span>
512 | </pane>
513 | </splitpanes>
514 |
515 | w-tabs(:items="2" content-class="pa0")
516 | template(#item-title.1) Composition API
517 | template(#item-content.1)
518 | ssh-pre.ma0.bd0(language="js").
519 | import { ref } from 'vue'
520 | import { Splitpanes, Pane } from 'splitpanes'
521 | import 'splitpanes/dist/splitpanes.css'
522 |
523 | const paneSize = ref(localStorage.paneSize ?? 30) // Read from persistent localStorage.
524 | const storePaneSize = ({ prevPane }) => {
525 | localStorage.paneSize = prevPane.size // Store in persistent localStorage.
526 | }
527 |
528 | const reloadPage = () => window.location.reload() // Button action to reload the page.
529 |
530 | template(#item-title.2) Options API
531 | template(#item-content.2)
532 | ssh-pre.ma0.bd0(language="js").
533 | import { Splitpanes, Pane } from 'splitpanes'
534 | import 'splitpanes/dist/splitpanes.css'
535 |
536 | export default {
537 | components: { Splitpanes, Pane },
538 | data: () => ({
539 | paneSize: localStorage.paneSize ?? 30, // Read from persistent localStorage.
540 | }),
541 | methods: {
542 | storePaneSize: ({ prevPane }) => {
543 | localStorage.paneSize = prevPane.size // Store in persistent localStorage.
544 | },
545 |
546 | reloadPage: () => window.location.reload() // Button action to reload the page.
547 | }
548 | }
549 |
550 | //- Example.
551 | h3.mt12.pt8.mb2(id="ex--in-depth-reactivity")
552 | a(href="#ex--in-depth-reactivity") In-depth reactivity
553 | p
554 | | This example shows the reactivity when you modify anything in your component inside splitpanes.#[br]
555 | w-button.mt2.mr2(@click="generateRandomNumber")
556 | w-icon.mr1(size="20") mdi mdi-sync
557 | | Generate 3 random numbers
558 | w-button.mt2(@click="incrementNumber(3)")
559 | w-icon.mr1(size="20") mdi mdi-plus
560 | | Increment pane #3
561 | splitpanes.default-theme.example(style="height: 400px" horizontal)
562 | pane
563 | splitpanes
564 | pane.w-flex.column.text-center(v-for="i in 3" :key="i")
565 | span {{ i }}#[br]
566 | em Number is: {{ randomNums[i] }}#[br]
567 | em(v-if="i === 2").
568 | Number on the left is: {{ randomNums[1] }}#[br]
569 | Number on the right is: {{ randomNums[3] }}#[br]
570 | w-button.align-center(v-if="i !== 2" @click="randomNums[i] = randomNums[i] + 1" style="min-width: 0")
571 | w-icon(size="20") mdi mdi-plus
572 | | 1
573 | pane.w-flex.column.text-center
574 | span 4#[br]
575 | em.
576 | - Nested splitpanes -#[br]
577 | [{{ randomNums[1] }}, {{ randomNums[2] }}, {{ randomNums[3] }}]
578 |
579 | ssh-pre(language="html-vue" label="HTML").
580 | <button @click="generateRandomNumber">Generate 3 random numbers</button>
581 | <button @click="incrementNumber(3)">Increment pane #3</button>
582 |
583 | <splitpanes horizontal class="default-theme" style="height: 400px">
584 | <pane>
585 | <splitpanes>
586 | <pane v-for="i in 3" :key="i">
587 | <span>{{ '\{\{ i \}\}' }}</span><br>
588 | <em>Number is: {{ '\{\{ randomNums[i] \}\}' }}</em><br>
589 | <em v-if="i === 2">
590 | Number on the left is: {{ '\{\{ randomNums[1] \}\}' }}<br>
591 | Number on the right is: {{ '\{\{ randomNums[3] \}\}' }}<br>
592 | </em>
593 | <button(v-if="i !== 2" @click="randomNums[i] = randomNums[i] + 1">+1</button>
594 | </pane>
595 | </splitpanes>
596 | </pane>
597 | <pane>
598 | <span>4</span><br>
599 | <em>
600 | - Nested splitpanes -<br>
601 | [{{ '\{\{ randomNums[1] \}\}' }}, {{ '\{\{ randomNums[2] \}\}' }}, {{ '\{\{ randomNums[1] \}\}' }}]
602 | </em>
603 | </pane>
604 | </splitpanes>
605 |
606 | w-tabs(:items="2" content-class="pa0")
607 | template(#item-title.1) Composition API
608 | template(#item-content.1)
609 | ssh-pre.ma0.bd0(language="js").
610 | import { ref } from 'vue'
611 | import { Splitpanes, Pane } from 'splitpanes'
612 | import 'splitpanes/dist/splitpanes.css'
613 |
614 | const randomNums = ref({ 1: 0, 2: 0, 3: 0 })
615 |
616 | const generateRandomNumber = () => {
617 | randomNums.value = Object.assign(randomNums.value, {
618 | 1: Math.round(Math.random() * 100),
619 | 2: Math.round(Math.random() * 100),
620 | 3: Math.round(Math.random() * 100)
621 | })
622 | }
623 |
624 | const incrementNumber = i => {
625 | randomNums.value[i]++
626 | }
627 |
628 | template(#item-title.2) Options API
629 | template(#item-content.2)
630 | ssh-pre.ma0.bd0(language="js").
631 | data: () => ({
632 | randomNums: { 1: 0, 2: 0, 3: 0 }
633 | }),
634 | methods: {
635 | generateRandomNumber () {
636 | this.randomNums = Object.assign(this.randomNums, {
637 | 1: Math.round(Math.random() * 100),
638 | 2: Math.round(Math.random() * 100),
639 | 3: Math.round(Math.random() * 100)
640 | })
641 | },
642 | incrementNumber (i) {
643 | this.randomNums[i]++
644 | }
645 | }
646 |
647 | //- Example.
648 | h3.mt12.pt8.mb2(id="ex--toggle-a-pane-with-v-if")
649 | a(href="#ex--toggle-a-pane-with-v-if") Toggle a pane with #[span.code v-if]
650 |
651 | w-button.mb2(@click="hidePane2 = !hidePane2")
652 | w-icon.mr2 mdi mdi-{{ hidePane2 ? 'eye' : 'eye-off' }}
653 | | {{ hidePane2 ? 'Show' : 'Hide' }} Pane 2
654 | splitpanes.default-theme.example(style="height: 400px")
655 | pane
656 | span 1
657 | pane.green-light5(v-if="!hidePane2")
658 | span 2
659 | pane
660 | span 3
661 |
662 | ssh-pre(language="html-vue" label="HTML").
663 | <button @click="hidePane2 = !hidePane2">{{ "\{\{ hidePane2 ? 'Show' : 'Hide' \}\}" }} Pane 2</button>
664 | <splitpanes class="default-theme" style="height: 400px">
665 | <pane>
666 | <span>1</span>
667 | </pane>
668 | <pane v-if="!hidePane2">
669 | <span>2</span>
670 | </pane>
671 | <pane>
672 | <span>3</span>
673 | </pane>
674 | </splitpanes>
675 |
676 | //- Example.
677 | h3.mt12.pt8.mb2(id="ex--resizable-drawer")
678 | a(href="#ex--resizable-drawer") Resizable Drawer
679 |
680 | p.
681 | Sometimes, you need a resizable drawer that goes on top of your app.#[br]
682 | Here's one way to do this, mostly thanks to CSS powers. The key here is to set the Splitpanes
683 | container to #[code pointer-events: none;] and reactivate the pointer events in the splitter and drawer
684 | so that you can click through Splitpanes on the rest of the page.
685 |
686 | w-button.mb2(@click="showDrawer = !showDrawer")
687 | w-icon.mr2 mdi mdi-{{ showDrawer ? 'eye' : 'eye-off' }}
688 | | {{ showDrawer ? 'Hide' : 'Show' }} Drawer
689 | splitpanes.default-theme.example.example--drawer(v-if="showDrawer")
690 | pane
691 | pane.drawer(size="40")
692 | h3.mt12 Resizable Drawer
693 |
694 | ssh-pre(language="html-vue" label="HTML").
695 | <button @click="showDrawer = !showDrawer">
696 | {{ "\{\{ showDrawer ? 'Hide' : 'Show' \}\}" }} Drawer
697 | </button>
698 |
699 | <splitpanes v-if="showDrawer" class="default-theme">
700 | <pane></pane>
701 | <pane size="40">
702 | <h3>Resizable Drawer</h3>
703 | </pane>
704 | </splitpanes>
705 |
706 | ssh-pre(language="css" label="CSS").
707 | .splitpanes {
708 | position: fixed;
709 | inset: 0 0 0 auto;
710 | z-index: 100;
711 | pointer-events: none;
712 |
713 | .splitpanes__pane:first-child {background-color: transparent;}
714 | .splitpanes__splitter {pointer-events: all;}
715 |
716 | .splitpanes__pane ~ .splitpanes__pane {
717 | pointer-events: all;
718 | background-color: #fff;
719 | box-shadow: none;
720 | align-items: flex-start;
721 | overflow: hidden;
722 | white-space: nowrap;
723 | }
724 | }
725 |
726 | //- Example.
727 | h3.mt12.pt8.mb2(id="ex--vue-router")
728 | a(href="#ex--vue-router") Vue Router inside splitpanes
729 | p.mb1.
730 | This is another reactivity example of a rather common case: Vue Router inside splitpanes.#[br]
731 | The navigation is in the left pane, but you can also access from outside of splitpanes, through those buttons:
732 | w-button.example-vue-router.my1.mr1(route="example-home-view") Home view
733 | w-button.example-vue-router.my1(route="example-another-view") Another view
734 |
735 | splitpanes.default-theme.example-vue-router.mt2(style="height: 400px")
736 | pane.w-flex.column.fill-height(min-size="20")
737 | .flex.pa2
738 | p.title1 Navigation
739 | ul
740 | li
741 | router-link(to="example-home-view") Home view
742 | li
743 | router-link(to="example-another-view") Another view
744 | em.ma-auto.grey I have a min width of 20%
745 | pane.w-flex.column.fill-height
746 | em.d-flex.justify-center.grey.code.pa2 router-view
747 | router-view.flex
748 | pane.w-flex.align-center.justify-center
749 | span.ma-auto 3#[br]
750 |
751 | ssh-pre(language="html-vue" label="HTML").
752 | <button to="home-view">Home view</button>
753 | <button to="another-view">Another view</button>
754 |
755 | <splitpanes horizontal class="default-theme" style="height: 400px">
756 | <pane min-size="20">
757 | <p>Navigation</p>
758 | <ul>
759 | <li><router-link to="home-view">Home view</li>
760 | <li><router-link to="another-view">Another view</li>
761 | </ul>
762 | </pane>
763 | <pane>
764 | <em>router-view</em>
765 | <router-view />
766 | </pane>
767 | <pane>
768 | <span>3</span>
769 | </pane>
770 | </splitpanes>
771 |
772 | ssh-pre(language="js" label="router.js").
773 | // Vue Router routes.
774 | routes: [
775 | {
776 | path: '/home-view',
777 | component: () => import('./components/home-view.vue')
778 | },
779 | {
780 | path: '/another-view',
781 | component: () => import('./components/another-view.vue')
782 | }
783 | ]
784 |
785 | ssh-pre(language="html-vue" label="home-view.vue").
786 | <template>
787 | <div class="green">
788 | <div>This is home</div>
789 | </div>
790 | </template>
791 |
792 | //- Example.
793 | h3.mt12.pt8.mb2(id="ex--emitted-events")
794 | a(href="#ex--emitted-events") Listening to emitted events
795 |
796 | p.mb2.
797 | Splitpanes fires several events that you can listen to. Here's a quick list, but you can also
798 | check the #[a(href="#emitted-events") Emitted Events section] for more details.
799 | ul.mt0
800 | li #[code ready]: When the component is ready.
801 | li #[code resize]: When a pane is being resized.
802 | li #[code resized]: When a pane has been resized.
803 | li #[code pane-click]: When a pane is clicked.
804 | li #[code pane-maximize]: When a pane is maximized.
805 | li #[code pane-add]: When a pane is added.
806 | li #[code pane-remove]: When a pane is removed.
807 | li #[code splitter-click]: When a splitter is clicked.
808 | li #[code splitter-dblclick]: When a splitter is double clicked.
809 | p.mt4 Try resizing panes and check the logs bellow.
810 |
811 | splitpanes.default-theme.example(
812 | @resize="log('resize', $event)"
813 | @resized="log('resized', $event)"
814 | @pane-maximize="log('pane-maximize', $event)"
815 | @pane-click="log('pane-click', $event)"
816 | @ready="log('ready', $event)"
817 | @splitter-click="log('splitter-click', $event)"
818 | @splitter-dblclick="log('splitter-dblclick', $event)"
819 | style="height: 400px")
820 | pane(v-for="i in 3" :key="i" :min-size="10")
821 | span {{ i }}
822 |
823 | pre.ssh-pre.logs-box(data-label="Logs")
824 | div.grey
825 | | //
826 | strong Event name:
827 | span Event params (Last event on top)
828 | div(v-for="(event, i) in logs" :key="i")
829 | strong {{ event.name }}:
830 | span {{ event.params }}
831 |
832 | ssh-pre(language="html-vue" label="HTML").
833 | <splitpanes
834 | class="default-theme"
835 | @resize="log('resize', $event)"
836 | @resized="log('resized', $event)"
837 | @pane-maximize="log('pane-maximize', $event)"
838 | @pane-click="log('pane-click', $event)"
839 | @ready="log('ready', $event)"
840 | @splitter-click="log('splitter-click', $event)"
841 | style="height: 400px">
842 | <pane v-for="i in 3" :key="i" min-size="10">
843 | <span>{{ '\{\{ i \}\}' }}</span>
844 | </pane>
845 | </splitpanes>
846 |
847 | //- Example.
848 | h3.mt12.pt8.mb2(id="ex--increased-touch-zone")
849 | a(href="#ex--increased-touch-zone") Increased reactive touch zone for touch devices
850 | p
851 | a(href="https://codepen.io/antoniandre/pen/XxRZmB" target="_blank")
852 | | Try it yourself on Codepen
853 | w-icon.ml1(color="primary") mdi mdi-open-in-new
854 |
855 | splitpanes.touch-example(horizontal style="height: 400px")
856 | pane
857 | splitpanes.touch-example
858 | pane
859 | span 1
860 | pane
861 | span 2
862 | pane
863 | span 3
864 | pane
865 | div.text
866 | p.
867 | In this example the splitters are thin lines but the reactive touch zone is spread to 30 pixels all around!
868 | #[em Hover a splitter to see the enlarged fat-finger-proof reactive zone.]
869 |
870 | ssh-pre(language="html-vue" label="HTML").
871 | <splitpanes horizontal style="height: 400px">
872 | <pane>
873 | <splitpanes>
874 | <pane>
875 | <span>1</span>
876 | </pane>
877 | <pane>
878 | <span>2</span>
879 | </pane>
880 | <pane>
881 | <span>3</span>
882 | </pane>
883 | </splitpanes>
884 | </pane>
885 | <pane>
886 | <p>In this example the splitters are thin lines but the reactive touch zone is spread to 30 pixels all around!</p>
887 | </pane>
888 | </splitpanes>
889 |
890 | ssh-pre(language="css" label="CSS").
891 | .splitpanes {background-color: #f8f8f8;}
892 |
893 | .splitpanes__splitter {background-color: #ccc;position: relative;}
894 | .splitpanes__splitter:before {
895 | content: '';
896 | position: absolute;
897 | left: 0;
898 | top: 0;
899 | transition: opacity 0.4s;
900 | background-color: rgba(255, 0, 0, 0.3);
901 | opacity: 0;
902 | z-index: 1;
903 | }
904 | .splitpanes__splitter:hover:before {opacity: 1;}
905 | .splitpanes--vertical > .splitpanes__splitter:before {left: -30px;right: -30px;height: 100%;}
906 | .splitpanes--horizontal > .splitpanes__splitter:before {top: -30px;bottom: -30px;width: 100%;}
907 |
908 | //- Example.
909 | h3.mt12.pt8.mb2(id="ex--do-your-own-style")
910 | a(href="#ex--do-your-own-style") Do your own style
911 | p If you don't want to use the default style, here is how to do your own.
912 | p
913 | a(href="https://codepen.io/antoniandre/pen/mzGZXR" target="_blank")
914 | | Try it yourself on Codepen
915 | w-icon.ml1(color="primary") mdi mdi-open-in-new
916 |
917 | splitpanes.example-own-style(horizontal style="height: 400px")
918 | pane
919 | splitpanes
920 | pane
921 | span 1
922 | pane
923 | span 2
924 | pane
925 | span 3
926 | pane
927 | span 4
928 |
929 | ssh-pre(language="html-vue" label="HTML").
930 | <splitpanes horizontal style="height: 400px">
931 | <pane>
932 | <splitpanes vertical>
933 | <pane>
934 | <span>1</span>
935 | </pane>
936 | <pane>
937 | <span>2</span>
938 | </pane>
939 | <pane>
940 | <span>3</span>
941 | </pane>
942 | </splitpanes>
943 | </pane>
944 | <pane>
945 | <span>4</span>
946 | </pane>
947 | </splitpanes>
948 |
949 | ssh-pre(language="css" label="CSS").
950 | .splitpanes {
951 | background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
952 | }
953 |
954 | .splitpanes__pane {
955 | box-shadow: 0 0 5px rgba(0, 0, 0, .2) inset;
956 | justify-content: center;
957 | align-items: center;
958 | display: flex;
959 | }
960 |
961 | .splitpanes--vertical > .splitpanes__splitter {
962 | min-width: 6px;
963 | background: linear-gradient(90deg, #ccc, #111);
964 | }
965 |
966 | .splitpanes--horizontal > .splitpanes__splitter {
967 | min-height: 6px;
968 | background: linear-gradient(0deg, #ccc, #111);
969 | }
970 |
971 | //- API section.
972 | h2.mt12.pt12.mb2(id="api")
973 | a(href="#api") API
974 |
975 | p Here is the list of all the props.
976 | ul
977 | li
978 | code horizontal
979 | span.code.ml2 Default: false
980 | p.
981 | The orientation of the panes splitting.#[br]
982 | Vertical by default, meaning the splitters are vertical, but you can resize horizontally
983 | li
984 | code push-other-panes
985 | span.code.ml2 Default: true
986 | p Whether it should push the next splitter when dragging a splitter until it reached another one.
987 | li
988 | code dbl-click-splitter
989 | span.code.ml2 Default: true
990 | p Double click on splitter to maximize the next pane.
991 | li
992 | code rtl
993 | span.code.ml2 Default: false
994 | p Supports Right to left direction.
995 | li
996 | code first-splitter
997 | span.code.ml2 Default: false
998 | p Displays the first splitter when set to true. This allows maximizing the first pane on splitter double click.
999 |
1000 | //- Emitted events section.
1001 | h2.mt12.pt12(id="emitted-events")
1002 | a(href="#emitted-events") Emitted Events
1003 | p.
1004 | Here is the list of events that are emitted from splitpanes along with their parameters.#[br]
1005 | View them in action in the #[a(href="#ex--emitted-events") Listening to emitted events] example.
1006 | ul
1007 | li
1008 | p.mb0
1009 | strong.code.mr2 ready
1010 | | Fires when splitpanes is ready. Returns an object containing:
1011 | ul.mt0
1012 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1013 | li
1014 | p.mb0
1015 | strong.code.mr2 resize
1016 | | Fires while resizing (on mousemove/touchmove). Returns an object containing:
1017 | ul.mt0
1018 | li #[strong.code event]: the native JavaScript event.
1019 | li #[strong.code index]: the index of the resizing splitter. The counter always starts from zero.
1020 | li #[strong.code prevPane]: the object of the previous pane (on the left if ltr, on the right if rtl, above if horizontal layout) from the splitter with its dimensions and DOM element.
1021 | li #[strong.code nextPane]: the object of the next pane (on the right if ltr, on the left if rtl, below if horizontal layout) from the splitter with its dimensions and DOM element.
1022 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1023 | li
1024 | p.mb0
1025 | strong.code.mr2 resized
1026 | | Fires after resizing (on mousemove/touchmove), or also after the free space redistribution
1027 | | occurring after adding or removing a pane. Returns an object containing:
1028 | ul.mt0
1029 | li #[strong.code event]: the native JavaScript event.
1030 | li #[strong.code index]: the index of the resizing splitter. The counter always starts from zero.
1031 | li #[strong.code prevPane]: the object of the previous pane (on the left if ltr, on the right if rtl, above if horizontal layout) from the splitter with its dimensions and DOM element.
1032 | li #[strong.code nextPane]: the object of the next pane (on the right if ltr, on the left if rtl, below if horizontal layout) from the splitter with its dimensions and DOM element.
1033 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1034 | li
1035 | p.mb0
1036 | strong.code.mr2 pane-click
1037 | | Fires on pane click/tap. Returns an object containing:
1038 | ul.mt0
1039 | li #[strong.code event]: the native JavaScript event.
1040 | li #[strong.code index]: the index of the pane. The counter starts from zero.
1041 | li #[strong.code pane]: the clicked pane object with its dimensions and DOM element.
1042 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1043 | li
1044 | p.mb0
1045 | strong.code.mr2 pane-maximize
1046 | | Fires on splitter double click/tap. Returns an object containing:
1047 | ul.mt0
1048 | li #[strong.code event]: the native JavaScript event.
1049 | li #[strong.code index]: the index of the pane. The counter starts from zero.
1050 | li #[strong.code pane]: the maximized pane object with its dimensions and DOM element.
1051 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1052 | li
1053 | p.mb0
1054 | strong.code.mr2 pane-add
1055 | | Fires on added pane. Returns an object containing:
1056 | ul.mt0
1057 | li #[strong.code event]: the native JavaScript event.
1058 | li #[strong.code pane]: the added pane object with its dimensions and DOM element.
1059 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1060 | li
1061 | p.mb0
1062 | strong.code.mr2 pane-remove
1063 | | Fires on removed pane. Returns an object containing:
1064 | ul.mt0
1065 | li #[strong.code event]: the native JavaScript event.
1066 | li #[strong.code pane]: the removed pane object with its dimensions.
1067 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1068 | li
1069 | p.mb0
1070 | strong.code.mr2 splitter-click
1071 | | Returns the next pane object (with its dimensions) directly after the clicked splitter.#[br]
1072 | | This event is only emitted if dragging did not occur between mousedown and mouseup.
1073 | ul.mt0
1074 | li #[strong.code event]: the native JavaScript event.
1075 | li #[strong.code index]: the index of the resizing splitter. The counter always starts from zero.
1076 | li #[strong.code prevPane]: the object of the previous pane (on the left if ltr, on the right if rtl, above if horizontal layout) from the splitter with its dimensions and DOM element.
1077 | li #[strong.code nextPane]: the object of the next pane (on the right if ltr, on the left if rtl, below if horizontal layout) from the splitter with its dimensions and DOM element.
1078 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1079 | li
1080 | p.mb0
1081 | strong.code.mr2 splitter-dblclick
1082 | | Fires when the user double clicks a splitter and returns the an object containing
1083 | ul.mt0
1084 | li #[strong.code event]: the native JavaScript event.
1085 | li #[strong.code index]: the index of the resizing splitter. The counter always starts from zero.
1086 | li #[strong.code prevPane]: the object of the previous pane (on the left if ltr, on the right if rtl, above if horizontal layout) from the splitter with its dimensions and DOM element.
1087 | li #[strong.code nextPane]: the object of the next pane (on the right if ltr, on the left if rtl, below if horizontal layout) from the splitter with its dimensions and DOM element.
1088 | li #[strong.code panes]: an array of all the panes objects with their dimensions.
1089 |
1090 | h2.mt12.pt12.mb2(id="release-notes")
1091 | a(href="#release-notes") Release Notes
1092 |
1093 | .mt6
1094 | strong.title2 Version 4.0.0
1095 | ul.mt1
1096 | li Emit #[code splitter-dblclick] on splitter dblclick event. (#120, #181, #182, #183)
1097 | li Renamed #[code dblClickSplitter] to #[code maximizePanes], and still on by default on splitter double click.
1098 | li.
1099 | Refactored all the emitted events to always return a single object containing as much information
1100 | as possible. E.g. event, index, pane, prevPane, nextPane, panes.
1101 |
1102 | .mt4
1103 | strong Version 3.2.0
1104 | ul.mt1
1105 | li Account for cursor position when dragging a splitter. (#204)
1106 | li Components fully rewritten with Composition API. Faster and more efficient resizing.
1107 | .mt6
1108 | | #[strong.title2.mr2 Version 3.0.0] For Vue 3 projects.
1109 | highlight-message(type="warning").
1110 | Installing the latest splitpanes on a Vue 2 project will break it.#[br]
1111 | For Vue 2, you need to install splitpanes from the #[span.code legacy] tag: #[code npm i splitpanes@legacy].#[br]
1112 | div #[strong Version 2.3.5] Prevent splitter double taps on touch devices if #[span.code `dblClickSplitter`] is set to false.
1113 | div #[strong Version 2.3.4] Fix removing pane DOM nodes in IE11
1114 | div #[strong Version 2.3.1] Fix firing #[span.code `pane-click`] event on pane click
1115 | div #[strong Version 2.3.0] Support rtl direction
1116 | div #[strong Version 2.2.0]
1117 | ul
1118 | li Added the #[span.code `firstSplitter`] option, disabled by default. ref: #[a(href="#change-direction") Change direction & first splitter]
1119 | li Adapt panes width and height after direction change. ref: #[a(href="#change-direction") Change direction & first splitter]
1120 | li Emit a #[span.code `resized`] event after pane was added/removed
1121 | li Emit a #[span.code `pane-add`] event after pane was added
1122 | li Emit a #[span.code `pane-remove`] event after pane was removed
1123 | li Support #[span.code `v-if`] on a Pane and allow inserting a Pane at any position between others. ref: #[a(href="#toggle-a-pane-with-v-if") Toggle a pane with v-if]
1124 |
1125 | .mt6
1126 | | #[strong.title2.mr2 Version 2.0.0] Fix reactivity issues.
1127 | highlight-message(type="success")
1128 | ul.mt1
1129 | li
1130 | strong.
1131 | Children must now be wrapped into a #[span.code `pane`] component.
1132 | li The attribute #[span.code `splitpanes-size`] is now replaced with #[span.code `size`] on the #[span.code `pane`] component.
1133 | li you can still add CSS classes on the #[span.code `pane`] component tag.
1134 |
1135 | div #[strong Version 1.14.0] Programmatically set pane size
1136 | div #[strong Version 1.13.0] Emit event on splitter click
1137 | div #[strong Version 1.12.0] double click splitter to maximize is now an option
1138 | div #[strong Version 1.11.0] Persist panes size after slots changed
1139 | div #[strong Version 1.10.0] Add maximum size feature on panes
1140 | div
1141 | | #[strong Version 1.9.0] Emit event on resize & watch slots optional
1142 | highlight-message.text-bold(type="success")
1143 | ul.mt0
1144 | li.
1145 | The #[span.code `resize`] event - previously firing after resize end - is now firing on resize.#[br]
1146 | A new #[span.code `resized`] event is emitted on resize end. Check out the
1147 | #[a(href="#emitted-events") Listening to emitted events] example.
1148 | li.
1149 | By default and for performance, the reactivity is now limited to slot deletion and slot creation.#[br]
1150 | With the option #[span.code `watchSlots`] you can also track any change on the slots.#[br]
1151 | div #[strong Version 1.8.0] Watch slots
1152 | div #[strong Version 1.7.0] Double click splitter to maximize next pane
1153 | div #[strong Version 1.6.0] Emit events
1154 | div #[strong Version 1.5.0] Add default size feature on panes
1155 | div #[strong Version 1.4.0] Add minimum size feature on panes
1156 | div #[strong Version 1.3.0] Splitpanes slots are now reactive (add/remove on the fly)
1157 | div #[strong Version 1.2.0] Add a `default-theme` CSS class to load default theme
1158 | div #[strong Version 1.1.0] Allow pushing other panes while dragging splitter
1159 | div #[strong Version 1.0.0] First public release
1160 |
1161 |
1162 |
1207 |
1208 |
1365 |
--------------------------------------------------------------------------------