├── .browserslistrc ├── .eslintrc.js ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── build-test.yml │ └── vuepress-deploy.yml ├── .gitignore ├── LICENSE ├── README-zh_CN.md ├── README.md ├── babel.config.js ├── dist ├── vue-grid-layout.common.js ├── vue-grid-layout.common.js.map ├── vue-grid-layout.umd.js ├── vue-grid-layout.umd.js.map ├── vue-grid-layout.umd.min.js └── vue-grid-layout.umd.min.js.map ├── jest.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── app.css ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ └── logo.png ├── components │ ├── CustomDragElement.vue │ ├── GridItem.vue │ ├── GridLayout.vue │ ├── TestElement.vue │ └── index.js ├── helpers │ ├── DOM.js │ ├── draggableUtils.js │ ├── responsiveUtils.js │ └── utils.js └── main.js ├── test ├── interact-test.html ├── interact-test.js └── unit │ ├── GridItem.spec.js │ └── utils.spec.js ├── vue.config.js ├── website ├── TODOS.md ├── docs │ ├── .vuepress │ │ ├── Autocomplete.js │ │ ├── components │ │ │ ├── Example01Basic.vue │ │ │ ├── Example02Events.vue │ │ │ ├── Example03MultipleGrids.vue │ │ │ ├── Example04AllowIgnore.vue │ │ │ ├── Example05Mirrored.vue │ │ │ ├── Example06Responsive.vue │ │ │ ├── Example07PreventCollision.vue │ │ │ ├── Example08ResponsivePredefinedLayouts.vue │ │ │ ├── Example09DynamicAddRemove.vue │ │ │ ├── Example10DragFromOutside.vue │ │ │ ├── Example11Bounded.vue │ │ │ ├── ExampleStylingGridLines.vue │ │ │ ├── ExampleStylingPlaceholder.vue │ │ │ ├── HomeFooter.vue │ │ │ └── HomepageGrid.vue │ │ ├── config.js │ │ ├── enhanceApp.js │ │ ├── public │ │ │ ├── assets │ │ │ │ ├── favicon │ │ │ │ │ └── apple-touch-icon.png │ │ │ │ └── img │ │ │ │ │ ├── docsfold-logo-sm.png │ │ │ │ │ ├── logo-jbay.png │ │ │ │ │ └── logo.png │ │ │ ├── examples │ │ │ │ ├── 01-basic.html │ │ │ │ ├── 01-basic.js │ │ │ │ ├── 02-events.html │ │ │ │ ├── 02-events.js │ │ │ │ ├── 03-multiple-grids.html │ │ │ │ ├── 04-allow-ignore.html │ │ │ │ ├── 05-mirrored.html │ │ │ │ ├── 06-responsive.html │ │ │ │ ├── 06-responsive.js │ │ │ │ ├── 07-prevent-collision.html │ │ │ │ ├── 07-prevent-collision.js │ │ │ │ ├── 08-responsive-predefined-layouts.html │ │ │ │ ├── 08-responsive-predefined-layouts.js │ │ │ │ ├── 09-dynamic-add-remove.html │ │ │ │ ├── 09-dynamic-add-remove.js │ │ │ │ ├── 10-drag-from-outside.html │ │ │ │ ├── 10-drag-from-outside.js │ │ │ │ ├── 11-bounded.html │ │ │ │ ├── 11-bounded.js │ │ │ │ ├── app.css │ │ │ │ ├── vue.js │ │ │ │ └── vue.min.js │ │ │ └── favicon.ico │ │ ├── styles │ │ │ └── index.styl │ │ └── theme │ │ │ ├── components │ │ │ ├── CarbonAds.vue │ │ │ └── Home.vue │ │ │ ├── index.js │ │ │ └── layouts │ │ │ └── Layout.vue │ ├── README.md │ ├── changelog │ │ └── README.md │ ├── guide │ │ ├── 01-basic.md │ │ ├── 02-events.md │ │ ├── 03-multiple-grids.md │ │ ├── 04-allow-ignore.md │ │ ├── 05-mirrored.md │ │ ├── 06-responsive.md │ │ ├── 07-prevent-collision.md │ │ ├── 08-responsive-predefined-layouts.md │ │ ├── 09-dynamic-add-remove.md │ │ ├── 10-drag-from-outside.md │ │ ├── 11-bounded.md │ │ ├── README.md │ │ ├── auto-size.md │ │ ├── events.md │ │ ├── examples.md │ │ ├── properties.md │ │ ├── styling.md │ │ └── usage.md │ ├── logo.png │ ├── logo.psd │ ├── logo.xcf │ └── zh │ │ ├── README.md │ │ ├── changelog │ │ └── README.md │ │ └── guide │ │ ├── 01-basic.md │ │ ├── 02-events.md │ │ ├── 03-multiple-grids.md │ │ ├── 04-allow-ignore.md │ │ ├── 05-mirrored.md │ │ ├── 06-responsive.md │ │ ├── 07-prevent-collision.md │ │ ├── 08-responsive-predefined-layouts.md │ │ ├── 09-dynamic-add-remove.md │ │ ├── 10-drag-from-outside.md │ │ ├── 11-bounded.md │ │ ├── README.md │ │ ├── auto-size.md │ │ ├── events.md │ │ ├── examples.md │ │ ├── properties.md │ │ ├── styling.md │ │ └── usage.md ├── package.json └── yarn.lock └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | 'eslint:recommended' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: jbaysolutions 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Software version (please complete the following information):** 11 | - Browser [e.g. chrome, safari] 12 | - Vue Version [e.g. 2.5.7] 13 | - vue-grid-layout Version: [e.g. 2.3.3] 14 | 15 | **Describe the bug** 16 | A clear and concise description of what the bug is. 17 | 18 | Please use the [CodeSandbox Template](https://codesandbox.io/s/5wy3rz5z1x?module=%2Fsrc%2FShowcaseLayout.js) to demonstrate your bug. It is much easier for us to help you if you do. 19 | 20 | 21 | **To Reproduce** 22 | Steps to reproduce the behavior: 23 | 1. Go to '...' 24 | 2. Click on '....' 25 | 3. Scroll down to '....' 26 | 4. See error 27 | 28 | **Expected behavior** 29 | A clear and concise description of what you expected to happen. 30 | 31 | **Screenshots** 32 | If applicable, add screenshots to help explain your problem. 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## If you have a feature request, please try to implement it before requesting it.
This is free software and the author is busy with other projects. 11 | 12 | **Is your feature request related to a problem? Please describe.** 13 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 14 | 15 | **Describe the solution you'd like** 16 | A clear and concise description of what you want to happen. 17 | 18 | **Describe alternatives you've considered** 19 | A clear and concise description of any alternative solutions or features you've considered. 20 | 21 | **Additional context** 22 | Add any other context or screenshots about the feature request here. 23 | -------------------------------------------------------------------------------- /.github/workflows/build-test.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [10.x, 12.x, 14.x, 15.x] 17 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Use Node.js ${{ matrix.node-version }} 22 | uses: actions/setup-node@v1 23 | with: 24 | node-version: ${{ matrix.node-version }} 25 | - name: Install dependency 26 | run: yarn 27 | - name: Lint check 28 | run: yarn lint 29 | - name: Build 30 | run: yarn build 31 | - name: Unit test 32 | run: yarn test:unit 33 | -------------------------------------------------------------------------------- /.github/workflows/vuepress-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy vuepress website 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | build-and-deploy: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@master 12 | 13 | - uses: actions/setup-node@v2 14 | with: 15 | node-version: '16' 16 | 17 | - name: vuepress-deploy 18 | uses: jenkey2011/vuepress-deploy@master 19 | env: 20 | ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} 21 | TARGET_REPO: jbaysolutions/vue-grid-layout 22 | TARGET_BRANCH: gh-pages 23 | BUILD_SCRIPT: cd website && yarn && yarn build 24 | BUILD_DIR: public 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | #/dist 4 | dist/demo.html 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw* 23 | 24 | yarn-error.log 25 | 26 | website/docs/dist 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 greyby 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. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Vue Grid Layout

2 | 3 |

vue-grid-layout

4 | 5 |

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 |

17 |

18 | Documentation Website 19 |

20 | 21 | ## What is Vue Grid Layout? 22 | 23 | vue-grid-layout is a grid layout system, like [Gridster](http://dsmorse.github.io/gridster.js/), for Vue.js. **Heavily inspired by [React-Grid-Layout](https://github.com/STRML/react-grid-layout)** 24 | 25 | ## Features 26 | 27 | * Draggable widgets 28 | * Resizable widgets 29 | * Static widgets 30 | * Bounds checking for dragging and resizing 31 | * Widgets may be added or removed without rebuilding grid 32 | * Layout can be serialized and restored 33 | * Automatic RTL support (resizing not working with RTL on 2.2.0) 34 | * Responsive 35 | 36 | ## **Current version:** 2.4.0 (Supports Vue 2.2+) 37 | 38 | #### **For legacy browsers**, like IE11, use version [2.3.12-legacy](https://github.com/jbaysolutions/vue-grid-layout/tree/legacy) 39 | #### **For Vue 2.1.10 and below use version [2.1.3](https://github.com/jbaysolutions/vue-grid-layout/tree/2.1.3)** 40 | #### **For Vue 1 use version [1.0.3](https://github.com/jbaysolutions/vue-grid-layout/tree/1.0.3)** 41 | 42 | ## Documentation 43 | 44 | Check out the Documentation Website 45 | 46 | 49 | 50 | #### Projects using vue-grid-layout 51 | 52 | - [DocsFold](https://www.docsfold.com/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) 53 | - [Draxed](https://www.draxed.com/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) 54 | - [Data Providers](https://www.dataproviders.io/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) 55 | - [Cataholic](https://cataholic.glitch.me/) 56 | 57 | *Know of others? Create a PR to let me know!* 58 | 59 | 60 | ## Contribute 61 | 62 | If you have a feature request, please add it as an issue or make a pull request. 63 | 64 | 65 | Developed by JBay Solutions 66 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app', 4 | '@babel/preset-env' 5 | ], 6 | "plugins": [ 7 | "transform-flow-comments" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'json', 5 | 'vue', 6 | ], 7 | moduleNameMapper: { 8 | '^@/(.*)$': '/src/$1', 9 | }, 10 | transformIgnorePatterns: [ 11 | "/node_modules/(?!@babel|@interactjs)", 12 | ], 13 | transform: { 14 | '^.+\\.js$': '/node_modules/babel-jest', 15 | '.*\\.(vue)$': '/node_modules/vue-jest', 16 | }, 17 | coverageDirectory: '/test/unit/coverage', 18 | collectCoverageFrom: [ 19 | 'src/**/*.{js,vue}', 20 | '!src/main.js', 21 | '!src/router/index.js', 22 | '!**/node_modules/**', 23 | ], 24 | }; 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-grid-layout", 3 | "version": "2.4.0", 4 | "description": "A draggable and resizable grid layout, as a Vue component.", 5 | "keywords": [ 6 | "grid", 7 | "vuejs", 8 | "drag", 9 | "draggable", 10 | "resize", 11 | "resizable", 12 | "fluid", 13 | "responsive" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/jbaysolutions/vue-grid-layout.git" 18 | }, 19 | "author": "Gustavo Santos (JBay Solutions) (http://www.jbaysolutions.com)", 20 | "homepage": "https://github.com/jbaysolutions/vue-grid-layout", 21 | "main": "dist/vue-grid-layout.common.js", 22 | "unpkg": "dist/vue-grid-layout.umd.min.js", 23 | "scripts": { 24 | "serve": "vue-cli-service serve", 25 | "build": "rimraf dist && vue-cli-service build", 26 | "build-lib": "rimraf dist && vue-cli-service build --target lib ./src/components/index.js", 27 | "lint": "vue-cli-service lint", 28 | "test:unit": "vue-cli-service test:unit", 29 | "test:cover": "vue-cli-service test:unit --coverage" 30 | }, 31 | "dependencies": { 32 | "@interactjs/actions": "1.10.2", 33 | "@interactjs/auto-scroll": "1.10.2", 34 | "@interactjs/auto-start": "1.10.2", 35 | "@interactjs/interactjs": "1.10.2", 36 | "@interactjs/modifiers": "1.10.2", 37 | "@interactjs/dev-tools": "1.10.2", 38 | "element-resize-detector": "^1.2.1" 39 | }, 40 | "devDependencies": { 41 | "@babel/preset-env": "^7.12.11", 42 | "@vue/cli-plugin-babel": "^3.4.1", 43 | "@vue/cli-plugin-eslint": "^3.4.1", 44 | "@vue/cli-plugin-unit-jest": "^4.5.10", 45 | "@vue/cli-service": "^3.4.1", 46 | "@vue/eslint-config-standard": "^3.0.5", 47 | "@vue/test-utils": "^1.1.2", 48 | "babel-core": "7.0.0-bridge.0", 49 | "babel-jest": "^26.6.3", 50 | "babel-plugin-transform-flow-comments": "^6.7.0", 51 | "rimraf": "^2.6.2", 52 | "vue": "^2.7.8", 53 | "vue-jest": "^3.0.7", 54 | "vue-template-compiler": "^2.7.8", 55 | "webpack-bundle-analyzer": "^3.9.0" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /public/app.css: -------------------------------------------------------------------------------- 1 | /*** EXAMPLE ***/ 2 | #content { 3 | width: 100%; 4 | margin-top:10px; 5 | } 6 | 7 | .vue-grid-layout { 8 | background: #eee; 9 | } 10 | 11 | .layoutJSON { 12 | background: #ddd; 13 | border: 1px solid black; 14 | margin-top: 10px; 15 | padding: 10px; 16 | } 17 | 18 | .eventsJSON { 19 | background: #ddd; 20 | border: 1px solid black; 21 | margin-top: 10px; 22 | padding: 10px; 23 | height: 100px; 24 | overflow-y: scroll; 25 | } 26 | 27 | .columns { 28 | -moz-columns: 120px; 29 | -webkit-columns: 120px; 30 | columns: 120px; 31 | } 32 | 33 | 34 | 35 | .vue-resizable-handle { 36 | z-index: 5000; 37 | position: absolute; 38 | width: 20px; 39 | height: 20px; 40 | bottom: 0; 41 | right: 0; 42 | background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4='); 43 | background-position: bottom right; 44 | padding: 0 3px 3px 0; 45 | background-repeat: no-repeat; 46 | background-origin: content-box; 47 | box-sizing: border-box; 48 | cursor: se-resize; 49 | } 50 | 51 | .vue-grid-item:not(.vue-grid-placeholder) { 52 | background: #ccc; 53 | border: 1px solid black; 54 | } 55 | 56 | .vue-grid-item.resizing { 57 | opacity: 0.9; 58 | } 59 | 60 | .vue-grid-item.static { 61 | background: #cce; 62 | } 63 | 64 | .vue-grid-item .text { 65 | font-size: 24px; 66 | text-align: center; 67 | position: absolute; 68 | top: 0; 69 | bottom: 0; 70 | left: 0; 71 | right: 0; 72 | margin: auto; 73 | height: 100%; 74 | width: 100%; 75 | } 76 | 77 | .vue-grid-item .no-drag { 78 | height: 100%; 79 | width: 100%; 80 | } 81 | 82 | .vue-grid-item .minMax { 83 | font-size: 12px; 84 | } 85 | 86 | .vue-grid-item .add { 87 | cursor: pointer; 88 | } 89 | 90 | .vue-draggable-handle { 91 | position: absolute; 92 | width: 20px; 93 | height: 20px; 94 | top: 0; 95 | left: 0; 96 | background: url("data:image/svg+xml;utf8,") no-repeat; 97 | background-position: bottom right; 98 | padding: 0 8px 8px 0; 99 | background-repeat: no-repeat; 100 | background-origin: content-box; 101 | box-sizing: border-box; 102 | cursor: pointer; 103 | } 104 | 105 | #content .vue-grid-item.vue-grid-placeholder { 106 | background-color: green; 107 | } 108 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Vue Grid Layout 12 | 13 | 14 | 18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/CustomDragElement.vue: -------------------------------------------------------------------------------- 1 | 8 | 24 | -------------------------------------------------------------------------------- /src/components/TestElement.vue: -------------------------------------------------------------------------------- 1 | 9 | 17 | 35 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import GridItem from './GridItem.vue'; 2 | import GridLayout from './GridLayout.vue'; 3 | // import ResponsiveGridLayout from './ResponsiveGridLayout.vue'; 4 | 5 | const VueGridLayout = { 6 | // ResponsiveGridLayout, 7 | GridLayout, 8 | GridItem 9 | } 10 | 11 | export function install(Vue) { 12 | if (install.installed) return; 13 | install.installed = true; 14 | Object.keys(VueGridLayout).forEach(name => { 15 | Vue.component(name, VueGridLayout[name]); 16 | }); 17 | } 18 | 19 | const plugin = { 20 | install, 21 | }; 22 | 23 | let GlobalVue = null; 24 | if (typeof window !== 'undefined') { 25 | GlobalVue = window.Vue; 26 | } else if (typeof global !== 'undefined') { 27 | GlobalVue = global.Vue; 28 | } 29 | if (GlobalVue) { 30 | GlobalVue.use(plugin); 31 | } 32 | 33 | export default VueGridLayout; 34 | export { GridLayout, GridItem }; 35 | -------------------------------------------------------------------------------- /src/helpers/DOM.js: -------------------------------------------------------------------------------- 1 | let currentDir: "ltr" | "rtl" | "auto" = "auto"; 2 | // let currentDir = "auto"; 3 | 4 | function hasDocument(){ 5 | return (typeof document !== "undefined"); 6 | } 7 | 8 | function hasWindow(){ 9 | return (typeof window !== "undefined"); 10 | } 11 | 12 | export function getDocumentDir(){ 13 | if(!hasDocument()){ 14 | return currentDir; 15 | } 16 | const direction = (typeof document.dir !== "undefined") ? 17 | document.dir : 18 | document.getElementsByTagName("html")[0].getAttribute("dir"); 19 | return direction; 20 | } 21 | 22 | export function setDocumentDir(dir: "ltr" | "rtl" | "auto"){ 23 | // export function setDocumentDir(dir){ 24 | if(!hasDocument){ 25 | currentDir = dir; 26 | return; 27 | } 28 | 29 | const html = document.getElementsByTagName("html")[0]; 30 | html.setAttribute("dir", dir); 31 | } 32 | 33 | export function addWindowEventListener(event:string, callback: () => mixed){ 34 | if(!hasWindow){ 35 | 36 | callback(); 37 | return; 38 | } 39 | window.addEventListener(event, callback); 40 | } 41 | 42 | export function removeWindowEventListener(event:string, callback: () => mixed){ 43 | if(!hasWindow){ 44 | return; 45 | } 46 | window.removeEventListener(event, callback); 47 | } 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/helpers/draggableUtils.js: -------------------------------------------------------------------------------- 1 | // Get {x, y} positions from event. 2 | export function getControlPosition(e) { 3 | return offsetXYFromParentOf(e); 4 | } 5 | 6 | 7 | // Get from offsetParent 8 | export function offsetXYFromParentOf(evt) { 9 | const offsetParent = evt.target.offsetParent || document.body; 10 | const offsetParentRect = evt.offsetParent === document.body ? {left: 0, top: 0} : offsetParent.getBoundingClientRect(); 11 | 12 | const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left; 13 | const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top; 14 | 15 | /*const x = Math.round(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left); 16 | const y = Math.round(evt.clientY + offsetParent.scrollTop - offsetParentRect.top);*/ 17 | 18 | 19 | return {x, y}; 20 | } 21 | 22 | 23 | // Create an data object exposed by 's events 24 | export function createCoreData(lastX, lastY, x, y) { 25 | // State changes are often (but not always!) async. We want the latest value. 26 | const isStart = !isNum(lastX); 27 | 28 | if (isStart) { 29 | // If this is our first move, use the x and y as last coords. 30 | return { 31 | deltaX: 0, deltaY: 0, 32 | lastX: x, lastY: y, 33 | x: x, y: y 34 | }; 35 | } else { 36 | // Otherwise calculate proper values. 37 | return { 38 | deltaX: x - lastX, deltaY: y - lastY, 39 | lastX: lastX, lastY: lastY, 40 | x: x, y: y 41 | }; 42 | } 43 | } 44 | 45 | 46 | function isNum(num) { 47 | return typeof num === 'number' && !isNaN(num); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/helpers/responsiveUtils.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import {cloneLayout, compact, correctBounds} from './utils'; 4 | 5 | import type {Layout} from './utils'; 6 | export type ResponsiveLayout = {lg?: Layout, md?: Layout, sm?: Layout, xs?: Layout, xxs?: Layout}; 7 | type Breakpoint = string; 8 | type Breakpoints = {lg?: number, md?: number, sm?: number, xs?: number, xxs?: number}; 9 | 10 | /** 11 | * Given a width, find the highest breakpoint that matches is valid for it (width > breakpoint). 12 | * 13 | * @param {Object} breakpoints Breakpoints object (e.g. {lg: 1200, md: 960, ...}) 14 | * @param {Number} width Screen width. 15 | * @return {String} Highest breakpoint that is less than width. 16 | */ 17 | export function getBreakpointFromWidth(breakpoints: Breakpoints, width: number): Breakpoint { 18 | const sorted = sortBreakpoints(breakpoints); 19 | let matching = sorted[0]; 20 | for (let i = 1, len = sorted.length; i < len; i++) { 21 | const breakpointName = sorted[i]; 22 | if (width > breakpoints[breakpointName]) matching = breakpointName; 23 | } 24 | return matching; 25 | } 26 | 27 | 28 | /** 29 | * Given a breakpoint, get the # of cols set for it. 30 | * @param {String} breakpoint Breakpoint name. 31 | * @param {Object} cols Map of breakpoints to cols. 32 | * @return {Number} Number of cols. 33 | */ 34 | export function getColsFromBreakpoint(breakpoint: Breakpoint, cols: Breakpoints): number { 35 | if (!cols[breakpoint]) { 36 | throw new Error("ResponsiveGridLayout: `cols` entry for breakpoint " + breakpoint + " is missing!"); 37 | } 38 | return cols[breakpoint]; 39 | } 40 | 41 | /** 42 | * Given existing layouts and a new breakpoint, find or generate a new layout. 43 | * 44 | * This finds the layout above the new one and generates from it, if it exists. 45 | * 46 | * @param {Array} orgLayout Original layout. 47 | * @param {Object} layouts Existing layouts. 48 | * @param {Array} breakpoints All breakpoints. 49 | * @param {String} breakpoint New breakpoint. 50 | * @param {String} breakpoint Last breakpoint (for fallback). 51 | * @param {Number} cols Column count at new breakpoint. 52 | * @param {Boolean} verticalCompact Whether or not to compact the layout 53 | * vertically. 54 | * @return {Array} New layout. 55 | */ 56 | export function findOrGenerateResponsiveLayout(orgLayout: Layout, layouts: ResponsiveLayout, breakpoints: Breakpoints, 57 | breakpoint: Breakpoint, lastBreakpoint: Breakpoint, 58 | cols: number, verticalCompact: boolean): Layout { 59 | // If it already exists, just return it. 60 | if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]); 61 | // Find or generate the next layout 62 | let layout = orgLayout; 63 | 64 | const breakpointsSorted = sortBreakpoints(breakpoints); 65 | const breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint)); 66 | for (let i = 0, len = breakpointsAbove.length; i < len; i++) { 67 | const b = breakpointsAbove[i]; 68 | if (layouts[b]) { 69 | layout = layouts[b]; 70 | break; 71 | } 72 | } 73 | layout = cloneLayout(layout || []); // clone layout so we don't modify existing items 74 | return compact(correctBounds(layout, {cols: cols}), verticalCompact); 75 | } 76 | 77 | export function generateResponsiveLayout(layout: Layout, breakpoints: Breakpoints, 78 | breakpoint: Breakpoint, lastBreakpoint: Breakpoint, 79 | cols: number, verticalCompact: boolean): Layout { 80 | // If it already exists, just return it. 81 | /*if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]); 82 | // Find or generate the next layout 83 | let layout = layouts[lastBreakpoint];*/ 84 | /*const breakpointsSorted = sortBreakpoints(breakpoints); 85 | const breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint)); 86 | for (let i = 0, len = breakpointsAbove.length; i < len; i++) { 87 | const b = breakpointsAbove[i]; 88 | if (layouts[b]) { 89 | layout = layouts[b]; 90 | break; 91 | } 92 | }*/ 93 | layout = cloneLayout(layout || []); // clone layout so we don't modify existing items 94 | return compact(correctBounds(layout, {cols: cols}), verticalCompact); 95 | } 96 | 97 | /** 98 | * Given breakpoints, return an array of breakpoints sorted by width. This is usually 99 | * e.g. ['xxs', 'xs', 'sm', ...] 100 | * 101 | * @param {Object} breakpoints Key/value pair of breakpoint names to widths. 102 | * @return {Array} Sorted breakpoints. 103 | */ 104 | export function sortBreakpoints(breakpoints: Breakpoints): Array { 105 | const keys: Array = Object.keys(breakpoints); 106 | return keys.sort(function(a, b) { 107 | return breakpoints[a] - breakpoints[b]; 108 | }); 109 | } 110 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | new Vue({ 5 | render: h => h(App) 6 | }).$mount('#app') 7 | -------------------------------------------------------------------------------- /test/interact-test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Interact TEST 6 | 7 | 30 | 31 | 32 |
33 |
34 | Resize from any edge or corner 35 |
36 |
37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /test/interact-test.js: -------------------------------------------------------------------------------- 1 | function dragMoveListener (event) { 2 | var target = event.target, 3 | // keep the dragged position in the data-x/data-y attributes 4 | x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx, 5 | y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy; 6 | 7 | // translate the element 8 | target.style.webkitTransform = 9 | target.style.transform = 10 | 'translate(' + x + 'px, ' + y + 'px)'; 11 | 12 | // update the posiion attributes 13 | target.setAttribute('data-x', x); 14 | target.setAttribute('data-y', y); 15 | } 16 | 17 | // this is used later in the resizing and gesture demos 18 | window.dragMoveListener = dragMoveListener; 19 | 20 | 21 | interact('.resize-drag') 22 | .draggable({ 23 | onmove: window.dragMoveListener, 24 | restrict: { 25 | restriction: 'parent', 26 | elementRect: { top: 0, left: 0, bottom: 1, right: 1 } 27 | }, 28 | }) 29 | .resizable({ 30 | // resize from all edges and corners 31 | edges: { left: true, right: true, bottom: true, top: true }, 32 | 33 | // keep the edges inside the parent 34 | restrictEdges: { 35 | outer: 'parent', 36 | endOnly: true, 37 | }, 38 | 39 | // minimum size 40 | restrictSize: { 41 | min: { width: 100, height: 50 }, 42 | }, 43 | 44 | inertia: true, 45 | }) 46 | .on('resizemove', function (event) { 47 | var target = event.target, 48 | x = (parseFloat(target.getAttribute('data-x')) || 0), 49 | y = (parseFloat(target.getAttribute('data-y')) || 0); 50 | 51 | // update the element's style 52 | target.style.width = event.rect.width + 'px'; 53 | target.style.height = event.rect.height + 'px'; 54 | 55 | // translate when resizing from top or left edges 56 | x += event.deltaRect.left; 57 | y += event.deltaRect.top; 58 | 59 | target.style.webkitTransform = target.style.transform = 60 | 'translate(' + x + 'px,' + y + 'px)'; 61 | 62 | target.setAttribute('data-x', x); 63 | target.setAttribute('data-y', y); 64 | target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height); 65 | }); -------------------------------------------------------------------------------- /test/unit/GridItem.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import GridLayout from '../../src/components/GridLayout.vue' 3 | 4 | let layout 5 | 6 | describe('GridLayout test', () => { 7 | beforeAll(()=>{ 8 | let testLayout = [{"x":0,"y":0,"w":2,"h":2,"i":"0", resizable: true, draggable: true, static: false, minY: 0, maxY: 2}]; 9 | layout = JSON.parse(JSON.stringify(testLayout)) 10 | }) 11 | 12 | describe('Interface test', () => { 13 | it('should render correct contents', () => { 14 | const wrapper = shallowMount(GridLayout, { 15 | propsData: { 16 | layout: layout 17 | } 18 | }) 19 | const grid = wrapper.findAll('.vue-grid-layout'); 20 | expect(grid.selector).toEqual('.vue-grid-layout'); 21 | }) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | // https://medium.com/js-dojo/how-to-reduce-your-vue-js-bundle-size-with-webpack-3145bf5019b7 2 | // const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 3 | const webpack = require('webpack'); 4 | const PACKAGE = require('./package.json'); 5 | 6 | const banner = PACKAGE.name + ' - ' + PACKAGE.version + ' | ' + 7 | '(c) 2015, ' + new Date().getFullYear() + ' ' + PACKAGE.author + ' | ' + 8 | PACKAGE.homepage; 9 | 10 | module.exports = { 11 | configureWebpack: { 12 | output: { 13 | library: "VueGridLayout", 14 | libraryExport: 'default' 15 | }, 16 | plugins: [ 17 | // new BundleAnalyzerPlugin(), 18 | new webpack.BannerPlugin(banner) 19 | ], 20 | }, 21 | css: { 22 | extract: false 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /website/TODOS.md: -------------------------------------------------------------------------------- 1 | # vue-grid-layout 2 | 3 | 4 | https://github.com/wearebraid/vueformulate.com/tree/master/docs 5 | 6 | 7 | # emit responsiveLayoutUpdatedEvent? 8 | 9 | https://github.com/jbaysolutions/vue-grid-layout/compare/master...wzquyin:master 10 | -------------------------------------------------------------------------------- /website/docs/.vuepress/Autocomplete.js: -------------------------------------------------------------------------------- 1 | // import MyFormulateAutocomplete from './components/MyFormulateAutocomplete' 2 | // 3 | // export default function (formulateInstance) { 4 | // formulateInstance.extend({ 5 | // components: { 6 | // MyFormulateAutocomplete 7 | // }, 8 | // library: { 9 | // autocomplete: { 10 | // classification: 'text', 11 | // component: 'MyFormulateAutocomplete' 12 | // } 13 | // } 14 | // }) 15 | // } 16 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example01Basic.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 71 | 72 | 133 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example03MultipleGrids.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 132 | 133 | 208 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example04AllowIgnore.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 130 | 131 | 205 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example05Mirrored.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 72 | 73 | 134 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example06Responsive.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 83 | 84 | 157 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example07PreventCollision.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 67 | 68 | 129 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example08ResponsivePredefinedLayouts.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 98 | 99 | 160 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example09DynamicAddRemove.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 85 | 86 | 169 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/Example11Bounded.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 80 | 81 | 154 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/ExampleStylingGridLines.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 88 | 89 | 169 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/ExampleStylingPlaceholder.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 73 | 74 | 139 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/HomeFooter.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | 16 | 34 | -------------------------------------------------------------------------------- /website/docs/.vuepress/components/HomepageGrid.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 86 | 87 | 218 | -------------------------------------------------------------------------------- /website/docs/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | const description = 'A draggable and resizable grid layout, as a Vue component.' 2 | const title = 'Vue Grid Layout - ️A grid layout system for Vue.js' 3 | 4 | module.exports = { 5 | base: "/vue-grid-layout/", 6 | locales: { 7 | '/': { 8 | lang: 'en-US', 9 | title: 'Vue Grid Layout - ️A grid layout system for Vue.js', 10 | description: 'A draggable and resizable grid layout, as a Vue component.' 11 | }, 12 | '/zh/': { 13 | lang: 'zh-CN', 14 | title: 'Vue Grid Layout -️ 适用Vue.js的栅格布局系统', 15 | description: '可拖动和可调整大小栅格布局的Vue组件。' 16 | } 17 | }, 18 | head: [ 19 | ['link', { rel: 'icon', href: `/favicon.ico` }], 20 | ['link', { rel: "apple-touch-icon", sizes: "180x180", href: "https://jbaysolutions.github.io/vue-grid-layout/assets/favicon/apple-touch-icon.png"}], 21 | // ['script', { src: 'https://cdn.jsdelivr.net/npm/vue-grid-layout@2.3.9/dist/vue-grid-layout.umd.min.js' }] 22 | [ 23 | 'script', 24 | { 25 | async: true, 26 | src: 'https://www.googletagmanager.com/gtag/js?id=G-9JZJJHRV8R', 27 | }, 28 | ], 29 | [ 30 | 'script', 31 | {}, 32 | [ 33 | "window.dataLayer = window.dataLayer || [];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js', new Date());\ngtag('config', 'G-9JZJJHRV8R');", 34 | ], 35 | ], 36 | ], 37 | port: 8081, 38 | theme: '@vuepress/vue', 39 | themeConfig: { 40 | smoothScroll: true, 41 | logo: '/assets/img/logo.png', 42 | repo: 'jbaysolutions/vue-grid-layout', 43 | docsDir: 'website/docs', 44 | editLinks: true, 45 | algolia: { 46 | apiKey: '2f143d1edd24605564065dd02bf0a22b', 47 | indexName: 'vue_grid_layout' 48 | }, 49 | locales: { 50 | '/': { 51 | selectText: 'Languages', 52 | label: 'English', 53 | ariaLabel: 'Select language', 54 | sidebar: { 55 | '/guide/': [ 56 | { 57 | title: "Guide", 58 | collapsable: false, 59 | children: [ 60 | '', 61 | 'usage', 62 | 'properties', 63 | 'events', 64 | 'styling', 65 | ] 66 | }, 67 | { 68 | title: "Examples", 69 | collapsable: false, 70 | children: [ 71 | '01-basic', 72 | '02-events', 73 | '03-multiple-grids', 74 | '04-allow-ignore', 75 | '05-mirrored', 76 | '06-responsive', 77 | '07-prevent-collision', 78 | '08-responsive-predefined-layouts', 79 | '09-dynamic-add-remove', 80 | '10-drag-from-outside', 81 | '11-bounded', 82 | ] 83 | } 84 | ] 85 | }, 86 | nav: [ 87 | {text: 'Home', link: '/'}, 88 | {text: 'Guide', link: '/guide/'}, 89 | {text: 'Changelog', link: '/changelog/'} 90 | ], 91 | searchPlaceholder: 'Search...', 92 | editLinkText: 'Help improve this page!', 93 | lastUpdated: 'Last Updated' 94 | }, 95 | '/zh/': { 96 | selectText: '选择语言', 97 | label: '简体中文', 98 | ariaLabel: '选择语言', 99 | sidebar: { 100 | '/zh/guide/': [ 101 | { 102 | title: "首页", 103 | collapsable: false, 104 | children: [ 105 | '', 106 | 'usage', 107 | 'properties', 108 | 'events', 109 | 'styling', 110 | ] 111 | }, 112 | { 113 | title: "例子", 114 | collapsable: false, 115 | children: [ 116 | '01-basic', 117 | '02-events', 118 | '03-multiple-grids', 119 | '04-allow-ignore', 120 | '05-mirrored', 121 | '06-responsive', 122 | '07-prevent-collision', 123 | '08-responsive-predefined-layouts', 124 | '09-dynamic-add-remove', 125 | '10-drag-from-outside', 126 | '11-bounded', 127 | ] 128 | } 129 | ] 130 | }, 131 | nav: [ 132 | {text: '首页', link: '/zh/'}, 133 | {text: '指南', link: '/zh/guide/'}, 134 | {text: '更新日志', link: '/zh/changelog/'} 135 | ], 136 | searchPlaceholder: '搜索...', 137 | editLinkText: '帮助改善此页面!', 138 | lastUpdated: '最后更新时间' 139 | } 140 | } 141 | }, 142 | plugins: [ 143 | '@vuepress/back-to-top', 144 | /*['@vuepress/google-analytics', { 145 | ga: 'UA-37288388-24' // UA-00000000-0 146 | }],*/ 147 | ['seo', { 148 | title: $page => `${$page.title} — Vue Grid Layout`, 149 | // image: () => 'https://jbaysolutions.github.io/vue-grid-layout/assets/img/og.jpg', 150 | siteTitle: (_, $site) => $site.title, 151 | description: $page => $page.frontmatter.description || description, 152 | author: (_, $site) => $site.themeConfig.author, 153 | tags: $page => $page.frontmatter.tags, 154 | twitterCard: _ => 'summary_large_image', 155 | type: () => 'article', 156 | url: (_, $site, path) => ($site.themeConfig.domain || '') + path, 157 | publishedAt: $page => $page.frontmatter.date && new Date($page.frontmatter.date), 158 | modifiedAt: $page => $page.lastUpdated && new Date($page.lastUpdated), 159 | }], 160 | ['vuepress-plugin-serve', { 161 | port: 8080, 162 | staticOptions: { 163 | dotfiles: 'allow', 164 | }, 165 | /*beforeServer(app, server) { 166 | app.get('/path/to/my/custom', function(req, res) { 167 | res.json({ custom: 'response' }) 168 | }) 169 | },*/ 170 | }], 171 | ], 172 | dest: 'public', 173 | } 174 | -------------------------------------------------------------------------------- /website/docs/.vuepress/enhanceApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * App level enhancements. Read more here: 3 | * https://vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements 4 | */ 5 | // import pageComponents from '@internal/page-components' 6 | import Autocomplete from './Autocomplete' 7 | // import ArticleCard from './components/ArticleCard' 8 | // import GithubButton from 'vue-github-button' 9 | // import VTooltip from 'v-tooltip' 10 | 11 | // import '../../node_modules/@braid/vue-formulate/themes/snow/snow.scss' 12 | 13 | export default ({ Vue }) => { 14 | /*Vue.prototype.$gridlayout = { 15 | async load () { 16 | await import('vue-grid-layout'); 17 | console.log("LOADED!") 18 | }, 19 | };*/ 20 | /*Vue.use(VueFormulate, { 21 | plugins: [ Autocomplete ] 22 | })*/ 23 | 24 | // Vue.use(VTooltip) 25 | 26 | // for (const [name, component] of Object.entries(pageComponents)) { 27 | // Vue.component(name, component) 28 | // } 29 | // Vue.component('github-button', GithubButton) 30 | // Vue.component('ArticleCard', ArticleCard) 31 | } 32 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/assets/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/website/docs/.vuepress/public/assets/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /website/docs/.vuepress/public/assets/img/docsfold-logo-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/website/docs/.vuepress/public/assets/img/docsfold-logo-sm.png -------------------------------------------------------------------------------- /website/docs/.vuepress/public/assets/img/logo-jbay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/website/docs/.vuepress/public/assets/img/logo-jbay.png -------------------------------------------------------------------------------- /website/docs/.vuepress/public/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/website/docs/.vuepress/public/assets/img/logo.png -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/01-basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue Grid Layout Example 1 - Basic 6 | 7 | 8 | 9 | 10 | 11 |

Vue Grid Layout Example 1 - Basic

12 | 13 | View project on Github 14 |
15 | Next example: Move and resize events 16 | 17 |
18 | 19 |
20 |
21 | Displayed as [x, y, w, h]: 22 |
23 |
24 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 25 |
26 |
27 |
28 |
29 |
30 | 33 | Draggable 34 | Resizable 35 |
36 | 44 | 52 | {{itemTitle(item)}} 53 | 54 | 55 |
56 | 57 |
58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/01-basic.js: -------------------------------------------------------------------------------- 1 | var testLayout = [ 2 | {"x":0,"y":0,"w":2,"h":2,"i":"0", static: false}, 3 | {"x":2,"y":0,"w":2,"h":4,"i":"1", static: true}, 4 | {"x":4,"y":0,"w":2,"h":5,"i":"2", static: false}, 5 | {"x":6,"y":0,"w":2,"h":3,"i":"3", static: false}, 6 | {"x":8,"y":0,"w":2,"h":3,"i":"4", static: false}, 7 | {"x":10,"y":0,"w":2,"h":3,"i":"5", static: false}, 8 | {"x":0,"y":5,"w":2,"h":5,"i":"6", static: false}, 9 | {"x":2,"y":5,"w":2,"h":5,"i":"7", static: false}, 10 | {"x":4,"y":5,"w":2,"h":5,"i":"8", static: false}, 11 | {"x":6,"y":3,"w":2,"h":4,"i":"9", static: true}, 12 | {"x":8,"y":4,"w":2,"h":4,"i":"10", static: false}, 13 | {"x":10,"y":4,"w":2,"h":4,"i":"11", static: false}, 14 | {"x":0,"y":10,"w":2,"h":5,"i":"12", static: false}, 15 | {"x":2,"y":10,"w":2,"h":5,"i":"13", static: false}, 16 | {"x":4,"y":8,"w":2,"h":4,"i":"14", static: false}, 17 | {"x":6,"y":8,"w":2,"h":4,"i":"15", static: false}, 18 | {"x":8,"y":10,"w":2,"h":5,"i":"16", static: false}, 19 | {"x":10,"y":4,"w":2,"h":2,"i":"17", static: false}, 20 | {"x":0,"y":9,"w":2,"h":3,"i":"18", static: false}, 21 | {"x":2,"y":6,"w":2,"h":2,"i":"19", static: false} 22 | ]; 23 | 24 | // var GridLayout = VueGridLayout.GridLayout; 25 | // var GridItem = VueGridLayout.GridItem; 26 | 27 | new Vue({ 28 | el: '#app', 29 | // components: { 30 | // "GridLayout": GridLayout, 31 | // "GridItem": GridItem 32 | // }, 33 | data: { 34 | layout: testLayout, 35 | draggable: true, 36 | resizable: true, 37 | index: 0 38 | }, 39 | 40 | /* 41 | mounted: function () { 42 | this.index = this.layout.length; 43 | }, 44 | */ 45 | methods: { 46 | itemTitle(item) { 47 | var result = item.i; 48 | if (item.static) { 49 | result += " - Static"; 50 | } 51 | return result; 52 | } 53 | /* 54 | increaseWidth: function(item) { 55 | var width = document.getElementById("content").offsetWidth; 56 | width += 20; 57 | document.getElementById("content").style.width = width+"px"; 58 | }, 59 | decreaseWidth: function(item) { 60 | 61 | var width = document.getElementById("content").offsetWidth; 62 | width -= 20; 63 | document.getElementById("content").style.width = width+"px"; 64 | }, 65 | removeItem: function(item) { 66 | //console.log("### REMOVE " + item.i); 67 | this.layout.splice(this.layout.indexOf(item), 1); 68 | }, 69 | addItem: function() { 70 | var self = this; 71 | //console.log("### LENGTH: " + this.layout.length); 72 | var item = {"x":0,"y":0,"w":2,"h":2,"i":this.index+"", whatever: "bbb"}; 73 | this.index++; 74 | this.layout.push(item); 75 | } 76 | */ 77 | } 78 | }); 79 | 80 | /* 81 | function generateLayout() { 82 | return _.map(_.range(0, 25), function (item, i) { 83 | var y = Math.ceil(Math.random() * 4) + 1; 84 | return { 85 | x: _.random(0, 5) * 2 % 12, 86 | y: Math.floor(i / 6) * y, 87 | w: 2, 88 | h: y, 89 | i: i.toString(), 90 | static: Math.random() < 0.05 91 | }; 92 | }); 93 | }*/ 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/02-events.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue Grid Layout Example 2 - Move and resize events 6 | 7 | 8 | 9 | 10 | 11 |

Vue Grid Layout Example 2 - Move and resize events

12 | 13 | View project on Github 14 |
15 | Previous example: Basic 16 |
17 | Next example: Multiple grids 18 | 19 |
20 | 21 |
22 |
23 | Displayed as [x, y, w, h]: 24 |
25 |
26 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 27 |
28 |
29 |
30 |
31 | Events: 32 |
33 | {{event}} 34 |
35 |
36 |
37 |
38 | 41 | 54 | 66 | {{item.i}} 67 | 68 | 69 |
70 | 71 | 72 |
73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/02-events.js: -------------------------------------------------------------------------------- 1 | var testLayout = [ 2 | {"x":0,"y":0,"w":2,"h":2,"i":"0"}, 3 | {"x":2,"y":0,"w":2,"h":4,"i":"1"}, 4 | {"x":4,"y":0,"w":2,"h":5,"i":"2"}, 5 | {"x":6,"y":0,"w":2,"h":3,"i":"3"}, 6 | {"x":8,"y":0,"w":2,"h":3,"i":"4"}, 7 | {"x":10,"y":0,"w":2,"h":3,"i":"5"}, 8 | {"x":0,"y":5,"w":2,"h":5,"i":"6"}, 9 | {"x":2,"y":5,"w":2,"h":5,"i":"7"}, 10 | {"x":4,"y":5,"w":2,"h":5,"i":"8"}, 11 | {"x":6,"y":4,"w":2,"h":4,"i":"9"}, 12 | {"x":8,"y":4,"w":2,"h":4,"i":"10"}, 13 | {"x":10,"y":4,"w":2,"h":4,"i":"11"}, 14 | {"x":0,"y":10,"w":2,"h":5,"i":"12"}, 15 | {"x":2,"y":10,"w":2,"h":5,"i":"13"}, 16 | {"x":4,"y":8,"w":2,"h":4,"i":"14"}, 17 | {"x":6,"y":8,"w":2,"h":4,"i":"15"}, 18 | {"x":8,"y":10,"w":2,"h":5,"i":"16"}, 19 | {"x":10,"y":4,"w":2,"h":2,"i":"17"}, 20 | {"x":0,"y":9,"w":2,"h":3,"i":"18"}, 21 | {"x":2,"y":6,"w":2,"h":2,"i":"19"} 22 | ]; 23 | 24 | new Vue({ 25 | el: '#app', 26 | data: { 27 | layout: testLayout, 28 | index: 0, 29 | eventLog: [] 30 | }, 31 | watch: { 32 | eventLog: function() { 33 | var eventsDiv = this.$refs.eventsDiv; 34 | eventsDiv.scrollTop = eventsDiv.scrollHeight; 35 | } 36 | }, 37 | methods: { 38 | moveEvent: function(i, newX, newY){ 39 | var msg = "MOVE i=" + i + ", X=" + newX + ", Y=" + newY; 40 | this.eventLog.push(msg); 41 | console.log(msg); 42 | 43 | }, 44 | movedEvent: function(i, newX, newY){ 45 | var msg = "MOVED i=" + i + ", X=" + newX + ", Y=" + newY; 46 | this.eventLog.push(msg); 47 | console.log(msg); 48 | 49 | }, 50 | resizeEvent: function(i, newH, newW, newHPx, newWPx){ 51 | var msg = "RESIZE i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx; 52 | this.eventLog.push(msg); 53 | console.log(msg); 54 | }, 55 | resizedEvent: function(i, newX, newY, newHPx, newWPx){ 56 | var msg = "RESIZED i=" + i + ", X=" + newX + ", Y=" + newY + ", H(px)=" + newHPx + ", W(px)=" + newWPx; 57 | this.eventLog.push(msg); 58 | console.log(msg); 59 | 60 | }, 61 | containerResizedEvent: function(i, newH, newW, newHPx, newWPx){ 62 | var msg = "CONTAINER RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx; 63 | this.eventLog.push(msg); 64 | console.log(msg); 65 | }, 66 | /** 67 | * 68 | * @param i the item id/index 69 | * @param newH new height in grid rows 70 | * @param newW new width in grid columns 71 | * @param newHPx new height in pixels 72 | * @param newWPx new width in pixels 73 | * 74 | */ 75 | resizedEvent: function(i, newH, newW, newHPx, newWPx){ 76 | var msg = "RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx; 77 | this.eventLog.push(msg); 78 | console.log(msg); 79 | }, 80 | 81 | layoutCreatedEvent: function(newLayout){ 82 | this.eventLog.push("Created layout"); 83 | console.log("Created layout: ", newLayout) 84 | }, 85 | layoutBeforeMountEvent: function(newLayout){ 86 | this.eventLog.push("beforeMount layout"); 87 | console.log("beforeMount layout: ", newLayout) 88 | }, 89 | layoutMountedEvent: function(newLayout){ 90 | this.eventLog.push("Mounted layout"); 91 | console.log("Mounted layout: ", newLayout) 92 | }, 93 | layoutReadyEvent: function(newLayout){ 94 | this.eventLog.push("Ready layout"); 95 | console.log("Ready layout: ", newLayout) 96 | }, 97 | layoutUpdatedEvent: function(newLayout){ 98 | this.eventLog.push("Updated layout"); 99 | console.log("Updated layout: ", newLayout) 100 | }, 101 | } 102 | }); 103 | 104 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/03-multiple-grids.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue Grid Layout Example 3 - Multiple grids 6 | 7 | 8 | 9 | 10 | 11 |

Vue Grid Layout Example 3 - Multiple grids

12 | 13 | View project on Github 14 |
15 | Previous example: Move and resize events 16 |
17 | Next example: Drag allow/ignore elements 18 | 19 | 20 |
21 |

Grid 1

22 |
23 |
24 | Displayed as [x, y, w, h]: 25 |
26 |
27 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 28 |
29 |
30 |
31 |
32 | 40 | 47 | {{item.i}} 48 | 49 | 50 |
51 |
52 |
53 |

Grid 2

54 |
55 |
56 | Displayed as [x, y, w, h]: 57 |
58 |
59 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 60 |
61 |
62 |
63 |
64 | 72 | 79 | {{item.i}} 80 | 81 | 82 |
83 | 84 | 85 | 86 | 113 | 114 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/04-allow-ignore.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue Grid Layout Example 4 - Drag allow/ignore elements 6 | 7 | 8 | 9 | 10 | 11 |

Vue Grid Layout Example 4 - Drag allow/ignore elements

12 | 13 | View project on Github 14 |
15 | Previous example: Multiple grids 16 |
17 | Next example: Mirrored grid layout 18 | 19 | 20 |
21 | 22 |
23 |
24 | Ignore drag on certain elements and allow on on others. 25 |
26 | Click and drag the dots on the corner of each item to reposition 27 |
28 | Displayed as [x, y, w, h]: 29 |
30 |
31 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 32 |
33 |
34 |
35 |
36 |
37 | 38 | 46 | 55 |
56 |
57 |
58 | {{item.i}} 59 |
60 | 61 |
62 |
63 |
64 |
65 |
66 | 67 |
68 | 69 | 70 | 71 | 104 | 105 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/05-mirrored.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue Grid Layout Example 4 - Mirrored grid layout 6 | 7 | 8 | 9 | 10 | 11 |

Vue Grid Layout Example 5 - Mirrored grid layout

12 | 13 | View project on Github 14 |
15 | Previous example: Drag allow/ignore elements 16 |
17 | Next example: Responsive 18 | 19 | 20 |
21 | 22 |
23 |
24 | Displayed as [x, y, w, h]: 25 |
26 |
27 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 28 |
29 |
30 |
31 |
32 |
33 | 36 | Draggable 37 | Resizable 38 | Mirrored 39 |
40 | 49 | 56 | {{item.i}} 57 | 58 | 59 |
60 | 61 |
62 | 63 | 64 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/06-responsive.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue Grid Layout Example 1 - Basic Responsive 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | Displayed as [x, y, w, h]: 16 |
17 |
18 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 19 |
20 |
21 |
22 |
23 |
24 | 27 | Draggable 28 | Resizable 29 | Responsive 30 |
31 | 41 | 48 | {{item.i}} 49 | 50 | 51 |
52 | 53 |
54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/06-responsive.js: -------------------------------------------------------------------------------- 1 | var testLayout = [ 2 | {"x":0,"y":0,"w":2,"h":2,"i":"0"}, 3 | {"x":2,"y":0,"w":2,"h":4,"i":"1"}, 4 | {"x":4,"y":0,"w":2,"h":5,"i":"2"}, 5 | {"x":6,"y":0,"w":2,"h":3,"i":"3"}, 6 | {"x":8,"y":0,"w":2,"h":3,"i":"4"}, 7 | {"x":10,"y":0,"w":2,"h":3,"i":"5"}, 8 | {"x":0,"y":5,"w":2,"h":5,"i":"6"}, 9 | {"x":2,"y":5,"w":2,"h":5,"i":"7"}, 10 | {"x":4,"y":5,"w":2,"h":5,"i":"8"}, 11 | {"x":6,"y":4,"w":2,"h":4,"i":"9"}, 12 | {"x":8,"y":4,"w":2,"h":4,"i":"10"}, 13 | {"x":10,"y":4,"w":2,"h":4,"i":"11"}, 14 | {"x":0,"y":10,"w":2,"h":5,"i":"12"}, 15 | {"x":2,"y":10,"w":2,"h":5,"i":"13"}, 16 | {"x":4,"y":8,"w":2,"h":4,"i":"14"}, 17 | {"x":6,"y":8,"w":2,"h":4,"i":"15"}, 18 | {"x":8,"y":10,"w":2,"h":5,"i":"16"}, 19 | {"x":10,"y":4,"w":2,"h":2,"i":"17"}, 20 | {"x":0,"y":9,"w":2,"h":3,"i":"18"}, 21 | {"x":2,"y":6,"w":2,"h":2,"i":"19"} 22 | ]; 23 | 24 | // var GridLayout = VueGridLayout.GridLayout; 25 | // var GridItem = VueGridLayout.GridItem; 26 | 27 | new Vue({ 28 | el: '#app', 29 | // components: { 30 | // "GridLayout": GridLayout, 31 | // "GridItem": GridItem 32 | // }, 33 | data: { 34 | layout: testLayout, 35 | draggable: true, 36 | resizable: true, 37 | responsive: true, 38 | index: 0, 39 | show: false, 40 | }, 41 | mounted: function () { 42 | this.index = this.layout.length; 43 | this.$nextTick(function () { 44 | this.show = true; 45 | }) 46 | }, 47 | /* methods: { 48 | increaseWidth: function(item) { 49 | var width = document.getElementById("content").offsetWidth; 50 | width += 20; 51 | document.getElementById("content").style.width = width+"px"; 52 | }, 53 | decreaseWidth: function(item) { 54 | 55 | var width = document.getElementById("content").offsetWidth; 56 | width -= 20; 57 | document.getElementById("content").style.width = width+"px"; 58 | }, 59 | removeItem: function(item) { 60 | //console.log("### REMOVE " + item.i); 61 | this.layout.splice(this.layout.indexOf(item), 1); 62 | }, 63 | addItem: function() { 64 | var self = this; 65 | //console.log("### LENGTH: " + this.layout.length); 66 | var item = {"x":0,"y":0,"w":2,"h":2,"i":this.index+"", whatever: "bbb"}; 67 | this.index++; 68 | this.layout.push(item); 69 | } 70 | } 71 | */ 72 | }); 73 | 74 | /* 75 | function generateLayout() { 76 | return _.map(_.range(0, 25), function (item, i) { 77 | var y = Math.ceil(Math.random() * 4) + 1; 78 | return { 79 | x: _.random(0, 5) * 2 % 12, 80 | y: Math.floor(i / 6) * y, 81 | w: 2, 82 | h: y, 83 | i: i.toString(), 84 | static: Math.random() < 0.05 85 | }; 86 | }); 87 | }*/ 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/07-prevent-collision.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vue Grid Layout Example 7 - Prevent Collision 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 |
17 | Displayed as [x, y, w, h]: 18 |
19 |
20 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 21 |
22 |
23 |
24 |
25 |
26 | 29 |
30 | 39 | 46 | {{item.i}} 47 | 48 | 49 |
50 | 51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/07-prevent-collision.js: -------------------------------------------------------------------------------- 1 | var testLayout = [ 2 | {"x":0,"y":0,"w":2,"h":5,"i":"0", static: false}, 3 | {"x":2,"y":0,"w":2,"h":2,"i":"1", static: false}, 4 | {"x":4,"y":0,"w":2,"h":5,"i":"2", static: false}, 5 | {"x":6,"y":0,"w":2,"h":3,"i":"3", static: false}, 6 | {"x":8,"y":0,"w":2,"h":3,"i":"4", static: false}, 7 | {"x":10,"y":0,"w":2,"h":3,"i":"5", static: false}, 8 | {"x":0,"y":5,"w":2,"h":5,"i":"6", static: false}, 9 | {"x":2,"y":5,"w":2,"h":5,"i":"7", static: false}, 10 | {"x":4,"y":5,"w":2,"h":5,"i":"8", static: false}, 11 | {"x":6,"y":3,"w":2,"h":4,"i":"9", static: false}, 12 | {"x":8,"y":4,"w":2,"h":4,"i":"10", static: false}, 13 | {"x":10,"y":4,"w":2,"h":4,"i":"11", static: false}, 14 | {"x":0,"y":10,"w":2,"h":5,"i":"12", static: false}, 15 | {"x":2,"y":10,"w":2,"h":5,"i":"13", static: false}, 16 | {"x":4,"y":8,"w":2,"h":4,"i":"14", static: false}, 17 | {"x":6,"y":8,"w":2,"h":4,"i":"15", static: false}, 18 | {"x":8,"y":10,"w":2,"h":5,"i":"16", static: false}, 19 | {"x":10,"y":4,"w":2,"h":2,"i":"17", static: false}, 20 | {"x":0,"y":9,"w":2,"h":3,"i":"18", static: false}, 21 | {"x":2,"y":6,"w":2,"h":2,"i":"19", static: false} 22 | ]; 23 | 24 | // var GridLayout = VueGridLayout.GridLayout; 25 | // var GridItem = VueGridLayout.GridItem; 26 | 27 | new Vue({ 28 | el: '#app', 29 | // components: { 30 | // "GridLayout": GridLayout, 31 | // "GridItem": GridItem 32 | // }, 33 | data: { 34 | layout: testLayout, 35 | draggable: true, 36 | resizable: true, 37 | index: 0 38 | }, 39 | 40 | /* 41 | mounted: function () { 42 | this.index = this.layout.length; 43 | }, 44 | */ 45 | methods: { 46 | itemTitle(item) { 47 | var result = item.i; 48 | if (item.static) { 49 | result += " - Static"; 50 | } 51 | return result; 52 | } 53 | } 54 | }); 55 | 56 | 57 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/08-responsive-predefined-layouts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vue Grid Layout Example 8 - Responsive with predefined layouts 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Vue Grid Layout Example 8 - Responsive with predefined layouts

14 | 15 | View project on Github 16 |
17 | Previous example: Prevent collision 18 |
19 | Next example: Dynamic Add/Remove 20 | 21 |
22 | 23 |
24 |
25 | Displayed as [x, y, w, h]: 26 |
27 |
28 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 29 |
30 |
31 |
32 |
33 |
34 | 37 | Draggable 38 | Resizable 39 | Responsive 40 |
41 | 52 | 59 | {{item.i}} 60 | 61 | 62 |
63 | 64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/08-responsive-predefined-layouts.js: -------------------------------------------------------------------------------- 1 | var testLayouts = { 2 | md: [ 3 | {"x":0, "y":0, "w":2, "h":2, "i":"0"}, 4 | {"x":2, "y":0, "w":2, "h":4, "i":"1"}, 5 | {"x":4, "y":0, "w":2, "h":5, "i":"2"}, 6 | {"x":6, "y":0, "w":2, "h":3, "i":"3"}, 7 | {"x":2, "y":4, "w":2, "h":3, "i":"4"}, 8 | {"x":4, "y":5, "w":2, "h":3, "i":"5"}, 9 | {"x":0, "y":2, "w":2, "h":5, "i":"6"}, 10 | {"x":2, "y":7, "w":2, "h":5, "i":"7"}, 11 | {"x":4, "y":8, "w":2, "h":5, "i":"8"}, 12 | {"x":6, "y":3, "w":2, "h":4, "i":"9"}, 13 | {"x":0, "y":7, "w":2, "h":4, "i":"10"}, 14 | {"x":2, "y":19, "w":2, "h":4, "i":"11"}, 15 | {"x":0, "y":14, "w":2, "h":5, "i":"12"}, 16 | {"x":2, "y":14, "w":2, "h":5, "i":"13"}, 17 | {"x":4, "y":13, "w":2, "h":4, "i":"14"}, 18 | {"x":6, "y":7, "w":2, "h":4, "i":"15"}, 19 | {"x":0, "y":19, "w":2, "h":5, "i":"16"}, 20 | {"x":8, "y":0, "w":2, "h":2, "i":"17"}, 21 | {"x":0, "y":11, "w":2, "h":3, "i":"18"}, 22 | {"x":2, "y":12, "w":2, "h":2, "i":"19"} 23 | ], 24 | lg: [ 25 | {"x":0,"y":0,"w":2,"h":2,"i":"0"}, 26 | {"x":2,"y":0,"w":2,"h":4,"i":"1"}, 27 | {"x":4,"y":0,"w":2,"h":5,"i":"2"}, 28 | {"x":6,"y":0,"w":2,"h":3,"i":"3"}, 29 | {"x":8,"y":0,"w":2,"h":3,"i":"4"}, 30 | {"x":10,"y":0,"w":2,"h":3,"i":"5"}, 31 | {"x":0,"y":5,"w":2,"h":5,"i":"6"}, 32 | {"x":2,"y":5,"w":2,"h":5,"i":"7"}, 33 | {"x":4,"y":5,"w":2,"h":5,"i":"8"}, 34 | {"x":6,"y":4,"w":2,"h":4,"i":"9"}, 35 | {"x":8,"y":4,"w":2,"h":4,"i":"10"}, 36 | {"x":10,"y":4,"w":2,"h":4,"i":"11"}, 37 | {"x":0,"y":10,"w":2,"h":5,"i":"12"}, 38 | {"x":2,"y":10,"w":2,"h":5,"i":"13"}, 39 | {"x":4,"y":8,"w":2,"h":4,"i":"14"}, 40 | {"x":6,"y":8,"w":2,"h":4,"i":"15"}, 41 | {"x":8,"y":10,"w":2,"h":5,"i":"16"}, 42 | {"x":10,"y":4,"w":2,"h":2,"i":"17"}, 43 | {"x":0,"y":9,"w":2,"h":3,"i":"18"}, 44 | {"x":2,"y":6,"w":2,"h":2,"i":"19"} 45 | ], 46 | }; 47 | 48 | // var GridLayout = VueGridLayout.GridLayout; 49 | // var GridItem = VueGridLayout.GridItem; 50 | 51 | new Vue({ 52 | el: '#app', 53 | // components: { 54 | // "GridLayout": GridLayout, 55 | // "GridItem": GridItem 56 | // }, 57 | data: { 58 | layouts: testLayouts, 59 | layout: testLayouts["lg"], 60 | draggable: true, 61 | resizable: true, 62 | responsive: true, 63 | index: 0 64 | }, 65 | mounted: function () { 66 | // this.index = this.layout.length; 67 | }, 68 | methods: { 69 | breakpointChangedEvent: function(newBreakpoint, newLayout){ 70 | console.log("BREAKPOINT CHANGED breakpoint=", newBreakpoint, ", layout: ", newLayout ); 71 | } 72 | } 73 | }); 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/09-dynamic-add-remove.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vue Grid Layout Example 9 - Dynamic Add/Remove 7 | 8 | 9 | 10 | 11 | 19 | 20 | 21 | 26 | 27 |
28 | 29 |
30 |
31 | Displayed as [x, y, w, h]: 32 |
33 |
34 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, 35 | {{item.h}}] 36 |
37 |
38 |
39 |
40 |
41 | 42 | Draggable 43 | Resizable 44 |
45 | 53 | 61 | {{item.i}} 62 | x 63 | 64 | 65 |
66 |
67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/09-dynamic-add-remove.js: -------------------------------------------------------------------------------- 1 | var testLayout = [ 2 | { x: 0, y: 0, w: 2, h: 2, i: "0" }, 3 | { x: 2, y: 0, w: 2, h: 2, i: "1" }, 4 | { x: 4, y: 0, w: 2, h: 2, i: "2" }, 5 | { x: 6, y: 0, w: 2, h: 2, i: "3" }, 6 | { x: 8, y: 0, w: 2, h: 2, i: "4" }, 7 | ]; 8 | 9 | // var GridLayout = VueGridLayout.GridLayout; 10 | // var GridItem = VueGridLayout.GridItem; 11 | 12 | new Vue({ 13 | el: "#app", 14 | // components: { 15 | // "GridLayout": GridLayout, 16 | // "GridItem": GridItem 17 | // }, 18 | data: { 19 | layout: testLayout, 20 | draggable: true, 21 | resizable: true, 22 | responsive: true, 23 | colNum: 12, 24 | index: 0, 25 | }, 26 | mounted: function () { 27 | this.index = this.layout.length; 28 | }, 29 | methods: { 30 | addItem: function () { 31 | // Add a new item. It must have a unique key! 32 | this.layout.push({ 33 | x: (this.layout.length * 2) % (this.colNum || 12), 34 | y: this.layout.length + (this.colNum || 12), // puts it at the bottom 35 | w: 2, 36 | h: 2, 37 | i: this.index, 38 | }); 39 | // Increment the counter to ensure key is always unique. 40 | this.index++; 41 | }, 42 | removeItem: function (val) { 43 | const index = this.layout.map(item => item.i).indexOf(val); 44 | this.layout.splice(index, 1); 45 | }, 46 | }, 47 | }); 48 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/10-drag-from-outside.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue Grid Layout Example 10 - Drag From Outside 6 | 7 | 8 | 9 | 19 | 20 | 21 | 22 |

Vue Grid Layout Example 09 - Drag From Outside

23 | 24 | View project on Github 25 |
26 | Previous example: Dynamic Add/Remove 27 |
28 | Next example: Bounded 29 | 30 |
31 | This demo shows what happens when an item is added from outside of the grid. 32 |
33 |
34 | Once you drop the item within the grid you'll get its coordinates/properties and can perform actions with it accordingly. 35 |
36 |
37 | 38 |
39 | 40 |
41 |
42 | Displayed as [x, y, w, h]: 43 |
44 |
45 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 46 |
47 |
48 |
49 |
50 |
51 |
Droppable Element (Drag me!)
52 |
53 | 62 | 69 | {{item.i}} 70 | 71 | 72 |
73 |
74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/10-drag-from-outside.js: -------------------------------------------------------------------------------- 1 | var testLayout = [ 2 | {"x":0,"y":0,"w":2,"h":2,"i":"0"}, 3 | {"x":2,"y":0,"w":2,"h":4,"i":"1"}, 4 | {"x":4,"y":0,"w":2,"h":5,"i":"2"}, 5 | {"x":6,"y":0,"w":2,"h":3,"i":"3"}, 6 | {"x":8,"y":0,"w":2,"h":3,"i":"4"}, 7 | {"x":10,"y":0,"w":2,"h":3,"i":"5"}, 8 | {"x":0,"y":5,"w":2,"h":5,"i":"6"}, 9 | {"x":2,"y":5,"w":2,"h":5,"i":"7"}, 10 | {"x":4,"y":5,"w":2,"h":5,"i":"8"}, 11 | {"x":5,"y":10,"w":4,"h":3,"i":"9"}, 12 | ]; 13 | var mouseXY={"x":null,"y":null}; 14 | var DragPos = {"x":null,"y":null,"w":1,"h":1,"i":null}; 15 | 16 | document.addEventListener("dragover", function(e) { 17 | mouseXY.x=e.clientX; 18 | mouseXY.y=e.clientY; 19 | }, false); 20 | 21 | new Vue({ 22 | el: '#app', 23 | data: { 24 | layout: testLayout, 25 | }, 26 | methods: { 27 | drag:function(e){ 28 | let parentRect = document.getElementById('content').getBoundingClientRect(); 29 | let mouseInGrid=false; 30 | if (((mouseXY.x>parentRect.left) && (mouseXY.xparentRect.top) && (mouseXY.y item.i === 'drop')) == -1){ 34 | this.layout.push({ 35 | x: (this.layout.length * 2) % (this.colNum || 12), 36 | y: this.layout.length + (this.colNum || 12), // puts it at the bottom 37 | w: 1, 38 | h: 1, 39 | i: 'drop', 40 | }); 41 | } 42 | let index=this.layout.findIndex(item => item.i === 'drop'); 43 | if (index!=-1){ 44 | try { 45 | this.$refs.gridLayout.$children[this.layout.length].$refs.item.style.display="none"; 46 | } catch { 47 | } 48 | let el=this.$refs.gridLayout.$children[index]; 49 | el.dragging={"top":mouseXY.y-parentRect.top,"left":mouseXY.x-parentRect.left}; 50 | let new_pos=el.calcXY(mouseXY.y-parentRect.top, mouseXY.x-parentRect.left); 51 | 52 | if (mouseInGrid==true){ 53 | this.$refs.gridLayout.dragEvent('dragstart', 'drop', new_pos.x,new_pos.y,1,1); 54 | DragPos.i=String(index); DragPos.x=this.layout[index].x; DragPos.y=this.layout[index].y; 55 | } 56 | if (mouseInGrid==false){ 57 | this.$refs.gridLayout.dragEvent('dragend', 'drop', new_pos.x,new_pos.y,1,1); 58 | this.layout = this.layout.filter(obj => obj.i !=='drop'); 59 | } 60 | } 61 | }, 62 | dragend:function(e){ 63 | let parentRect = document.getElementById('content').getBoundingClientRect(); 64 | let mouseInGrid=false; 65 | if (((mouseXY.x>parentRect.left) && (mouseXY.xparentRect.top) && (mouseXY.y obj.i !=='drop'); 72 | 73 | // UNCOMMENT below if you want to add a grid-item 74 | /* 75 | this.layout.push({ 76 | x: DragPos.x, 77 | y: DragPos.y, 78 | w: 1, 79 | h: 1, 80 | i: DragPos.i, 81 | }); 82 | this.$refs.gridLayout.dragEvent('dragend', DragPos.i, DragPos.x,DragPos.y,1,1); 83 | try { 84 | this.$refs.gridLayout.$children[this.layout.length].$refs.item.style.display="block"; 85 | } catch { 86 | } 87 | */ 88 | } 89 | }, 90 | }, 91 | }); 92 | 93 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/11-bounded.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vue Grid Layout Example 11 - Bounded 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Vue Grid Layout Example 11 - Bounded

14 | 15 | View project on Github 16 |
17 | Previous example: Drag From Outside 18 |
19 | 20 | 21 |
22 | 23 |
24 |
25 | Displayed as [x, y, w, h]: 26 |
27 |
28 | {{item.i}}: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}] 29 |
30 |
31 |
32 |
33 |
34 | Draggable 35 | Resizable 36 | Bounded 37 |
38 | 47 | 54 | {{item.i}} 55 | 56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/11-bounded.js: -------------------------------------------------------------------------------- 1 | var testLayout = [ 2 | {"x":0,"y":0,"w":2,"h":2,"i":"0"}, 3 | {"x":2,"y":0,"w":2,"h":4,"i":"1"}, 4 | {"x":4,"y":0,"w":2,"h":5,"i":"2"}, 5 | {"x":6,"y":0,"w":2,"h":3,"i":"3"}, 6 | {"x":8,"y":0,"w":2,"h":3,"i":"4"}, 7 | {"x":10,"y":0,"w":2,"h":3,"i":"5"}, 8 | {"x":0,"y":5,"w":2,"h":5,"i":"6"}, 9 | {"x":2,"y":5,"w":2,"h":5,"i":"7"}, 10 | {"x":4,"y":5,"w":2,"h":5,"i":"8"}, 11 | {"x":6,"y":4,"w":2,"h":4,"i":"9"}, 12 | {"x":8,"y":4,"w":2,"h":4,"i":"10"}, 13 | {"x":10,"y":4,"w":2,"h":4,"i":"11"}, 14 | {"x":0,"y":10,"w":2,"h":5,"i":"12"}, 15 | {"x":2,"y":10,"w":2,"h":5,"i":"13"}, 16 | {"x":4,"y":8,"w":2,"h":4,"i":"14"}, 17 | {"x":6,"y":8,"w":2,"h":4,"i":"15"}, 18 | {"x":8,"y":10,"w":2,"h":5,"i":"16"}, 19 | {"x":10,"y":4,"w":2,"h":2,"i":"17"}, 20 | {"x":0,"y":9,"w":2,"h":3,"i":"18"}, 21 | {"x":2,"y":6,"w":2,"h":2,"i":"19"} 22 | ]; 23 | 24 | new Vue({ 25 | el: '#app', 26 | data: { 27 | layout: testLayout, 28 | draggable: true, 29 | resizable: true, 30 | bounded: true 31 | } 32 | }); 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/examples/app.css: -------------------------------------------------------------------------------- 1 | /*** EXAMPLE ***/ 2 | #content { 3 | width: 100%; 4 | } 5 | 6 | .vue-grid-layout { 7 | background: #eee; 8 | } 9 | 10 | .layoutJSON { 11 | background: #ddd; 12 | border: 1px solid black; 13 | margin-top: 10px; 14 | padding: 10px; 15 | } 16 | 17 | .eventsJSON { 18 | background: #ddd; 19 | border: 1px solid black; 20 | margin-top: 10px; 21 | padding: 10px; 22 | height: 100px; 23 | overflow-y: scroll; 24 | } 25 | 26 | .columns { 27 | -moz-columns: 120px; 28 | -webkit-columns: 120px; 29 | columns: 120px; 30 | } 31 | 32 | 33 | 34 | /*.vue-resizable-handle { 35 | z-index: 5000; 36 | position: absolute; 37 | width: 20px; 38 | height: 20px; 39 | bottom: 0; 40 | right: 0; 41 | background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4='); 42 | background-position: bottom right; 43 | padding: 0 3px 3px 0; 44 | background-repeat: no-repeat; 45 | background-origin: content-box; 46 | box-sizing: border-box; 47 | cursor: se-resize; 48 | }*/ 49 | 50 | .vue-grid-item:not(.vue-grid-placeholder) { 51 | background: #ccc; 52 | border: 1px solid black; 53 | } 54 | 55 | .vue-grid-item.resizing { 56 | opacity: 0.9; 57 | } 58 | 59 | .vue-grid-item.static { 60 | background: #cce; 61 | } 62 | 63 | .vue-grid-item .text { 64 | font-size: 24px; 65 | text-align: center; 66 | position: absolute; 67 | top: 0; 68 | bottom: 0; 69 | left: 0; 70 | right: 0; 71 | margin: auto; 72 | height: 100%; 73 | width: 100%; 74 | } 75 | 76 | .vue-grid-item .no-drag { 77 | height: 100%; 78 | width: 100%; 79 | } 80 | 81 | .vue-grid-item .minMax { 82 | font-size: 12px; 83 | } 84 | 85 | .vue-grid-item .add { 86 | cursor: pointer; 87 | } 88 | 89 | .vue-draggable-handle { 90 | position: absolute; 91 | width: 20px; 92 | height: 20px; 93 | top: 0; 94 | left: 0; 95 | background: url("data:image/svg+xml;utf8,") no-repeat; 96 | background-position: bottom right; 97 | padding: 0 8px 8px 0; 98 | background-repeat: no-repeat; 99 | background-origin: content-box; 100 | box-sizing: border-box; 101 | cursor: pointer; 102 | } 103 | -------------------------------------------------------------------------------- /website/docs/.vuepress/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/website/docs/.vuepress/public/favicon.ico -------------------------------------------------------------------------------- /website/docs/.vuepress/styles/index.styl: -------------------------------------------------------------------------------- 1 | // placeholder for test, dont't remove it. 2 | 3 | //.content { 4 | // font-size 30px; 5 | //} 6 | 7 | //div.theme-default-content:not(.custom) { max-width: 100%; } 8 | div.theme-default-content:not(.custom) { max-width: 1024px; } 9 | 10 | 11 | /* 12 | pre.vue-container 13 | border-left-width: .5rem; 14 | border-left-style: solid; 15 | border-color: #42b983; 16 | border-radius: 0px; 17 | & > code 18 | font-size: 14px !important; 19 | & > p 20 | margin: -5px 0 -20px 0; 21 | code 22 | background-color: #42b983 !important; 23 | padding: 3px 5px; 24 | border-radius: 3px; 25 | color #000 26 | em 27 | color #808080 28 | font-weight light 29 | 30 | */ 31 | -------------------------------------------------------------------------------- /website/docs/.vuepress/theme/components/CarbonAds.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 66 | 67 | 130 | -------------------------------------------------------------------------------- /website/docs/.vuepress/theme/components/Home.vue: -------------------------------------------------------------------------------- 1 | 62 | 63 | 85 | 86 | 184 | -------------------------------------------------------------------------------- /website/docs/.vuepress/theme/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extend: '@vuepress/theme-default' 3 | } 4 | -------------------------------------------------------------------------------- /website/docs/.vuepress/theme/layouts/Layout.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 30 | 31 | 50 | -------------------------------------------------------------------------------- /website/docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: HomeLayout 3 | home: true 4 | heroImage: /assets/img/logo.png 5 | heroText: Vue Grid Layout 6 | tagline: A grid layout system for Vue.js, like Gridster, for Vue.js. Heavily inspired by React-Grid-Layout 7 | actionText: Get Started → 8 | actionLink: /guide/ 9 | features: 10 | - title: ✥ Draggable widgets 11 | details: 12 | - title: ⇲ Resizable widgets 13 | details: 14 | - title: Static widgets 15 | details: 16 | - title: Bounds checking for dragging and resizing 17 | details: 18 | - title: Widgets can be added or removed without rebuilding grid 19 | details: 20 | - title: Layout can be serialized and restored 21 | details: 22 | - title: Automatic RTL support (resizing not working with RTL on 2.2.0) 23 | details: 24 | - title: Responsive 25 | details: 26 | - title: Min/max w/h per item 27 | details: 28 | --- 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /website/docs/guide/01-basic.md: -------------------------------------------------------------------------------- 1 | # 01 - Basic 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example01Basic.vue) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /website/docs/guide/02-events.md: -------------------------------------------------------------------------------- 1 | # 02 - Move and resize events 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example02Events.vue) 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /website/docs/guide/03-multiple-grids.md: -------------------------------------------------------------------------------- 1 | # 03 - Multiple grids 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example03MultipleGrids.vue) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /website/docs/guide/04-allow-ignore.md: -------------------------------------------------------------------------------- 1 | # 04 - Drag allow/ignore elements 2 | 3 | Ignore drag on certain elements and allow on others. 4 | 5 | Click and drag the dots on the corner of each item to reposition 6 | 7 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example04AllowIgnore.vue) 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /website/docs/guide/05-mirrored.md: -------------------------------------------------------------------------------- 1 | # 05 - Mirrored grid layout 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example05Mirrored.vue) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /website/docs/guide/06-responsive.md: -------------------------------------------------------------------------------- 1 | # 06 - Responsive 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example06Responsive.vue) 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /website/docs/guide/07-prevent-collision.md: -------------------------------------------------------------------------------- 1 | # 07 - Prevent Collision 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example07PreventCollision.vue) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /website/docs/guide/08-responsive-predefined-layouts.md: -------------------------------------------------------------------------------- 1 | # 08 - Responsive with predefined layouts 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example08ResponsivePredefinedLayouts.vue) 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /website/docs/guide/09-dynamic-add-remove.md: -------------------------------------------------------------------------------- 1 | # 09 - Dynamic Add/Remove 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example09DynamicAddRemove.vue) 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /website/docs/guide/10-drag-from-outside.md: -------------------------------------------------------------------------------- 1 | # 10 - Drag From Outside 2 | 3 | This demo shows what happens when an item is added from outside of the grid. 4 |
5 | Once you drop the item within the grid you'll get its coordinates/properties and can perform actions with it accordingly. 6 | 7 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example10DragFromOutside.vue) 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /website/docs/guide/11-bounded.md: -------------------------------------------------------------------------------- 1 | # 11 - Dragging grid items bounded to grid container 2 | 3 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example11Bounded.vue) 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /website/docs/guide/README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## NPM 4 | 5 | npm install vue-grid-layout --save 6 | 7 | ## Yarn 8 | 9 | yarn add vue-grid-layout 10 | 11 | 12 | Import the library 13 | 14 | ```javascript 15 | import VueGridLayout from 'vue-grid-layout'; 16 | ``` 17 | 18 | Add to other Vue components 19 | 20 | ```javascript 21 | export default { 22 | components: { 23 | GridLayout: VueGridLayout.GridLayout, 24 | GridItem: VueGridLayout.GridItem 25 | }, 26 | // ... data, methods, mounted (), etc. 27 | } 28 | 29 | ``` 30 | 31 | ## browser 32 | 33 | Include the browser-ready bundle (download from [releases](https://github.com/jbaysolutions/vue-grid-layout/releases)) in your page. The components will be automatically available. 34 | 35 | ```html 36 | 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /website/docs/guide/auto-size.md: -------------------------------------------------------------------------------- 1 | # Auto Sizing Grid Items 2 | 3 | TODO: https://github.com/jbaysolutions/vue-grid-layout/issues/351 4 | -------------------------------------------------------------------------------- /website/docs/guide/events.md: -------------------------------------------------------------------------------- 1 | # Events 2 | 3 | Move and resize event listeners can be added to each grid-item, so that the parent Vue can be notified when a grid element is being moved or resized. 4 | Moved and resized event listeners can be added, if the only notification needed is when an item is finished moving or resizing. 5 | 6 | Working example [here](../guide/02-events.md) 7 | 8 | ````html 9 | 10 | 26 | 27 | 39 | {{item.i}} 40 | 41 | 42 | ```` 43 | 44 | ## GridLayout 45 | 46 | ### layoutCreatedEvent 47 | 48 | Layout created event 49 | 50 | Emited on the component created lifecycle hook 51 | 52 | ```javascript 53 | layoutCreatedEvent: function(newLayout){ 54 | console.log("Created layout: ", newLayout) 55 | } 56 | ``` 57 | 58 | ### layoutBeforeMountEvent 59 | 60 | Layout beforeMount event 61 | 62 | Emited on the component beforeMount lifecycle hook 63 | 64 | ```javascript 65 | layoutBeforeMountEvent: function(newLayout){ 66 | console.log("beforeMount layout: ", newLayout) 67 | } 68 | ``` 69 | 70 | ### layoutMountedEvent 71 | 72 | Layout mounted event 73 | 74 | Emited on the component mounted lifecycle hook 75 | 76 | ```javascript 77 | layoutMountedEvent: function(newLayout){ 78 | console.log("Mounted layout: ", newLayout) 79 | } 80 | ``` 81 | 82 | ### layoutReadyEvent 83 | 84 | Layout ready event 85 | 86 | Emited when all the operations on the mount hook finish 87 | 88 | ```javascript 89 | layoutReadyEvent: function(newLayout){ 90 | console.log("Ready layout: ", newLayout) 91 | } 92 | ``` 93 | 94 | ### layoutUpdatedEvent 95 | 96 | Layout updated event 97 | 98 | Every time the layout has finished updating and positions of all grid-items are recalculated 99 | 100 | ```javascript 101 | layoutUpdatedEvent: function(newLayout){ 102 | console.log("Updated layout: ", newLayout) 103 | } 104 | ``` 105 | 106 | 107 | ### breakpointChangedEvent 108 | 109 | Breakpoint Changed event 110 | 111 | Every time the breakpoint value changes due to window resize 112 | 113 | ```javascript 114 | /** 115 | * 116 | * @param newBreakpoint the breakpoint name 117 | * @param newLayout the chosen layout for the breakpoint 118 | * 119 | */ 120 | breakpointChangedEvent: function(newBreakpoint, newLayout){ 121 | console.log("BREAKPOINT CHANGED breakpoint=", newBreakpoint, ", layout: ", newLayout ); 122 | }, 123 | ``` 124 | 125 | 126 | ## GridItem 127 | 128 | ### moveEvent 129 | 130 | Move event 131 | 132 | Every time an item is being moved and changes position 133 | 134 | ```javascript 135 | moveEvent: function(i, newX, newY){ 136 | console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY); 137 | }, 138 | ``` 139 | 140 | ### resizeEvent 141 | 142 | Resize event 143 | 144 | Every time an item is being resized and changes size 145 | 146 | ```javascript 147 | resizeEvent: function(i, newH, newW, newHPx, newWPx){ 148 | console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 149 | }, 150 | ``` 151 | 152 | ### movedEvent 153 | 154 | Moved event 155 | 156 | Every time an item is finished being moved and changes position 157 | 158 | ```javascript 159 | movedEvent: function(i, newX, newY){ 160 | console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY); 161 | }, 162 | ``` 163 | 164 | ### resizedEvent 165 | 166 | Resized event 167 | 168 | Every time an item is finished being resized and changes size 169 | 170 | ```javascript 171 | /** 172 | * 173 | * @param i the item id/index 174 | * @param newH new height in grid rows 175 | * @param newW new width in grid columns 176 | * @param newHPx new height in pixels 177 | * @param newWPx new width in pixels 178 | * 179 | */ 180 | resizedEvent: function(i, newH, newW, newHPx, newWPx){ 181 | console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 182 | }, 183 | ``` 184 | 185 | ### containerResizedEvent 186 | 187 | Container Resized event 188 | 189 | Every time the grid item/layout container changes size (browser window or other) 190 | 191 | ```javascript 192 | /** 193 | * 194 | * @param i the item id/index 195 | * @param newH new height in grid rows 196 | * @param newW new width in grid columns 197 | * @param newHPx new height in pixels 198 | * @param newWPx new width in pixels 199 | * 200 | */ 201 | containerResizedEvent: function(i, newH, newW, newHPx, newWPx){ 202 | console.log("CONTAINER RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 203 | }, 204 | ``` 205 | 206 | -------------------------------------------------------------------------------- /website/docs/guide/examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | ## Basic 4 | 5 | 6 | 7 | ## Events 8 | 9 | 10 | 11 | ## Multiple Grids 12 | 13 | 14 | 15 | ## Drag allow/ignore elements 16 | 17 | Ignore drag on certain elements and allow on on others. 18 | 19 | Click and drag the dots on the corner of each item to reposition 20 | 21 | 22 | -------------------------------------------------------------------------------- /website/docs/guide/styling.md: -------------------------------------------------------------------------------- 1 | # Styling 2 | 3 | Grid styling can be customized to fit your needs. Below is a list of the classes you can override. 4 | 5 | ## Placeholder 6 | 7 | The default css for the placeholder is: 8 | 9 | ````css 10 | .vue-grid-item.vue-grid-placeholder { 11 | background: red; 12 | opacity: 0.2; 13 | transition-duration: 100ms; 14 | z-index: 2; 15 | -webkit-user-select: none; 16 | -moz-user-select: none; 17 | -ms-user-select: none; 18 | -o-user-select: none; 19 | user-select: none; 20 | } 21 | ```` 22 | 23 | You can override the properties using the !important rule: 24 | 25 | ````css 26 | .vue-grid-item.vue-grid-placeholder { 27 | background: green !important; 28 | } 29 | ```` 30 | 31 | Or by wrapping your grid with a more [specific](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) class: 32 | 33 | ````css 34 | .container .vue-grid-item.vue-grid-placeholder { 35 | background: green; 36 | } 37 | ```` 38 | 39 | In this example we change the placeholder background color to green: 40 | 41 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/ExampleStylingPlaceholder.vue) 42 | 43 | 44 | 45 | 46 | 47 | 48 | ## Grid lines 49 | 50 | To add grid lines to the layout, add the ``grid`` class to the grid-layout element and use the css: 51 | 52 | ````css 53 | .grid::before { 54 | content: ''; 55 | background-size: calc(calc(100% - 5px) / 12) 40px; 56 | background-image: linear-gradient( 57 | to right, 58 | lightgrey 1px, 59 | transparent 1px 60 | ), 61 | linear-gradient(to bottom, lightgrey 1px, transparent 1px); 62 | height: calc(100% - 5px); 63 | width: calc(100% - 5px); 64 | position: absolute; 65 | background-repeat: repeat; 66 | margin:5px; 67 | } 68 | ```` 69 | 70 | CSS calculations for grid lines: 71 | 72 | * background size = calc(calc(100% - (margin/2)) / colNum) rowHeight + margin; 73 | * height: calc(100% - (margin/2)) 74 | * width: calc(100% - (margin/2)) 75 | * margin: margin / 2 76 | 77 | [View source](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/ExampleStylingGridLines.vue) 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | Work in progress... 86 | -------------------------------------------------------------------------------- /website/docs/guide/usage.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | ```javascript 4 | new Vue({ 5 | el: '#app', 6 | data: { 7 | layout: [ 8 | {"x":0,"y":0,"w":2,"h":2,"i":"0"}, 9 | {"x":2,"y":0,"w":2,"h":4,"i":"1"}, 10 | {"x":4,"y":0,"w":2,"h":5,"i":"2"}, 11 | {"x":6,"y":0,"w":2,"h":3,"i":"3"}, 12 | {"x":8,"y":0,"w":2,"h":3,"i":"4"}, 13 | {"x":10,"y":0,"w":2,"h":3,"i":"5"}, 14 | {"x":0,"y":5,"w":2,"h":5,"i":"6"}, 15 | {"x":2,"y":5,"w":2,"h":5,"i":"7"}, 16 | {"x":4,"y":5,"w":2,"h":5,"i":"8"}, 17 | {"x":6,"y":3,"w":2,"h":4,"i":"9"}, 18 | {"x":8,"y":4,"w":2,"h":4,"i":"10"}, 19 | {"x":10,"y":4,"w":2,"h":4,"i":"11"}, 20 | {"x":0,"y":10,"w":2,"h":5,"i":"12"}, 21 | {"x":2,"y":10,"w":2,"h":5,"i":"13"}, 22 | {"x":4,"y":8,"w":2,"h":4,"i":"14"}, 23 | {"x":6,"y":8,"w":2,"h":4,"i":"15"}, 24 | {"x":8,"y":10,"w":2,"h":5,"i":"16"}, 25 | {"x":10,"y":4,"w":2,"h":2,"i":"17"}, 26 | {"x":0,"y":9,"w":2,"h":3,"i":"18"}, 27 | {"x":2,"y":6,"w":2,"h":2,"i":"19"} 28 | ], 29 | }, 30 | }); 31 | ``` 32 | 33 | 34 | ```html 35 | 36 | 47 | 48 | 55 | {{item.i}} 56 | 57 | 58 | ``` 59 | -------------------------------------------------------------------------------- /website/docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/website/docs/logo.png -------------------------------------------------------------------------------- /website/docs/logo.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/website/docs/logo.psd -------------------------------------------------------------------------------- /website/docs/logo.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbaysolutions/vue-grid-layout/6e536767937fbde7f1f18435a185e2b9a00c27ef/website/docs/logo.xcf -------------------------------------------------------------------------------- /website/docs/zh/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: HomeLayout 3 | home: true 4 | heroImage: /assets/img/logo.png 5 | heroText: Vue Grid Layout 6 | tagline: 一个类似于Gridster的栅格布局系统, 适用于Vue.js。灵感源自于React-Grid-Layout 7 | actionText: 开始 → 8 | actionLink: /zh/guide/ 9 | features: 10 | - title: ✥ 可拖拽 11 | details: 12 | - title: ⇲ 可调整大小 13 | details: 14 | - title: 静态部件(不可拖拽、调整大小) 15 | details: 16 | - title: 拖拽和调整大小时进行边界检查 17 | details: 18 | - title: 增减部件时避免重建栅格 19 | details: 20 | - title: 可序列化和还原的布局 21 | details: 22 | - title: 自动化 RTL 支持 23 | details: 24 | - title: 响应式 25 | details: 26 | - title: Min/max w/h per item 27 | details: 28 | --- 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /website/docs/zh/changelog/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: auto 3 | --- 4 | # 更新日志 5 | 6 | ## 2.4.0(2022年08月03日) 7 | 8 | * TODO 9 | 10 | ## 2.3.12(2021年01月15日) 11 | 12 | * 将interact.js升级到1.10.2 13 | * 向GridItem添加了'preserveAspectRatio'属性 (感谢 [validide](https://github.com/validide)) 14 | 15 | ## 2.3.11(2020年10月13日) 16 | 17 | * 已修复:使用响应式布局时的回归(#487) 18 | 19 | ## 2.3.10(2020年10月12日) 20 | 21 | * 将interact.js升级到1.10.0,现在作为ES6模块导入以优化大小 22 | * 已修复:在RTL模式下无法调整栅格元素的大小 (感谢 [or-lat](https://github.com/or-lat)) 23 | * 添加了GridLayout.useStyleCursor属性以修复可能的浏览器冻结 (感谢 [mosuzi](https://github.com/mosuzi)) 24 | * 已修复:当GridItem不是GridLayout的子级时,父布局错误 (感谢 [lzq4047](https://github.com/lzq4047)) 25 | * 已修复:在响应模式下再次隐藏/显示元素时,元素的大小发生变化 (感谢 [lustan3216](https://github.com/lustan3216))) 26 | 27 | ## 2.3.9(2020年9月28日) 28 | 29 | * 已修复插件安装(已修复#311) (感谢 [yfwz100](https://github.com/yfwz100)) 30 | * interact.js升级版本至1.9.22 31 | 32 | ## 2.3.8(2020年7月31日) 33 | 34 | * 支持动态修改margin属性 (感谢 [yfwz100](https://github.com/yfwz100)) 35 | * 添加了丢失的“布局更新”事件 (感谢 [ben-lau](https://github.com/ben-lau)) 36 | * 支持初始响应式布局和断点更改事件 (感谢 [ftylitak](https://github.com/ftylitak)) 37 | * 修正了布局项被删除且未设置interactObj时可能出现的错误 (感谢 [Tofandel](https://github.com/Tofandel)) 38 | * 在响应模式下修复错误的栅格元素排序 (感谢 [pieterbeulque](https://github.com/pieterbeulque)) 39 | 40 | ## 2.3.7(2019年10月31日) 41 | 42 | * 在#337中引入容器更改大小(浏览器窗口或其他大小)时发出的重命名“调整大小”事件,在#358已修复 43 | * 已修复layout-ready事件 44 | 45 | ## 2.3.6(2019年9月11日) 46 | 47 | * 恢复栅格元素w和h先前的舍入更改,已修复#355 48 | 49 | ## 2.3.5(2019年9月7日) 50 | 51 | * 已修复:在移动设备上无触摸,并且仅当元素可拖动或可调整大小时 (感谢 [DGoms](https://github.com/DGoms))。 52 | * 防止碰撞功能 (感谢 [SheanDe](https://github.com/SheanDe))。 53 | * 简体中文README (感谢 [harrywangchina](https://github.com/harrywangchina))。 54 | * 如果由于除手动调整大小(例如,浏览器窗口调整大小)以外的更改而调整了栅格项的大小,则此时将发出`resized`事件 (感谢 [pmorch](https://github.com/pmorch))。 55 | * 改进`layout-ready`触发事件 (感谢 [pmorch](https://github.com/pmorch))。 56 | * 添加了min/max height and width的监视程序 (感谢 [grinat](https://github.com/grinat))。 57 | * 改进:确保grid-item的大小大于slot-item (感谢 [ywmail](https://github.com/ywmail))。 58 | 59 | ## 2.3.4(2019年3月5日) 60 | 61 | * 支持静态部件 (感谢 [panjiangyi](https://github.com/panjiangyi))。 62 | * RTL错误修正 (感谢 [irvingwa](https://github.com/irvingwa))。 63 | * 内存泄漏修复 (感谢 [aiankile](https://github.com/aiankile))。 64 | * 已修复了栅格布局安装上的异常 (感谢 [BenoitZugmeyer](https://github.com/BenoitZugmeyer))。 65 | * 已修复了响应模式下重叠和调整大小的错误 (感谢 [shpfive](https://github.com/shpfive))。 66 | * 添加了GridLayout发出的新事件 (layout-created, layout-before-mount,layout-mounted,layout-ready) (感谢 [samuelmolinski](https://github.com/samuelmolinski))。 67 | 68 | ## 2.3.3(2018年12月26日) 69 | 70 | * 恢复了将vue作为外部添加,这导致加载umd时出现问题。 71 | 72 | ## 2.3.2(2018年12月13日) 73 | 74 | * 添加了vue作为外部webpack配置以修复启动问题 (感谢 [Micene9](https://github.com/Micene09)) 75 | 76 | ## 2.3.1(2018年11月6日) 77 | 78 | * 之前在Android上进行触摸拖动的修复方法打破了在其他移动浏览器上的拖动 (感谢 [onx2](https://github.com/onx2)) 79 | 80 | 81 | ## 2.3.0(2018年10月26日) 82 | 83 | * 响应式布局支持 (感谢 [shpfive](https://github.com/shpfive)) 84 | * 已修复了在Android上进行触摸拖动的问题 (感谢 [pbabey](https://github.com/pbabey)) 85 | 86 | ## 2.2.0(2018年9月10日) 87 | 88 | * 使用Vue CLI更改了项目结构并进行了构建 89 | * GridItem新的autosize方法。现在,需要使用this.$parent.autoSize()从子组件中调用 (感谢 [mech01nc01](https://github.com/mech01nc01)) 90 | * 抽象的DOM相关要求提供初始SSR支持 (感谢 [Kukks](https://github.com/Kukks)) 91 | * GridItem.i现在可以是数字或字符串 (感谢 [xch1029](https://github.com/xch1029)) 92 | * 使用interactjs大小来限制调整大小 (感谢 [LuisCarreras](https://github.com/LuisCarreras)) 93 | * 已修复了实例释放时的interactjs实例泄漏 (感谢 [zzuligy](https://github.com/zzuligy)) 94 | 95 | ## 2.1.13(2018年5月2日) 96 | 97 | * 调整大小事件现在也发出以像素为单位的尺寸 (感谢 [buremba](https://github.com/buremba)) 98 | * 支持动态列修改(#121) (感谢 [ittus](https://github.com/ittus)) 99 | 100 | ## 2.1.12(2018年2月27日) 101 | 102 | * 将interact.js更新为1.3.3 (#144) 103 | 104 | ## 2.1.11(2018年1月5日) 105 | 106 | * 解决了同一个虚拟机(#134)上有多个栅格的问题 (感谢 [Suen](https://github.com/sunzongzheng)) 107 | * 解决了重新分配时布局更新的问题(#130) (感谢 [daizengyu](https://github.com/daizengyu123)) 108 | 109 | ## 2.1.10(2017年12月15日) 110 | 111 | * 已修复了与#119相关的可能错误 112 | * 将CSS转换为Translation3D(#96) 113 | * 添加了is-mirrored配置,允许从右向左渲染栅格元素(水平翻转) (感谢 [kweij](https://github.com/kweij)) 114 | * 添加了栅格更新事件,可以更轻松地与vuex集成 (感谢 [SergeyKhval](https://github.com/SergeyKhval)) 115 | 116 | ## 2.1.9(2017年8月17日) 117 | 118 | * 已修复了对interact.js的本地模块引用 119 | 120 | ## 2.1.8(2017年8月17日) 121 | 122 | * 已修复#61、#37 123 | * 已修复#82 124 | * 已修复#87 125 | 126 | ## 2.1.7(2017年8月17日) 127 | 128 | * 已修复#59 129 | * 已修复#83 130 | * 对GridItem中props的dragAllowFrom和dragIgnoreFrom实现了支持 (感谢 [ThePlastic](https://github.com/ThePlastic)) 131 | 132 | ## 2.1.6(2017年4月6日) 133 | 134 | * 已修复#43,配置拖曳元件上的栅格项内容忽略 (感谢 [neithere](https://github.com/neithere)) 135 | * 已修复了getLayoutItem,有时返回null元素 (感谢 [pbabey](https://github.com/pbabey)) 136 | 137 | ## 2.1.5(2017年3月24日) 138 | 139 | * 真正修复#22、#32,多个栅格实例在2.1.4中无法正常工作 140 | * resizeEvent现在还以像素为单位返回元素的宽度和高度(实现#34) 141 | 142 | 143 | ## 2.1.4(2017年3月20日) 144 | 145 | * 实现#32,在同一页面上支持多个栅格实例 146 | 147 | ## 2.1.3(2017年3月9日) 148 | 149 | * 已修复#27, props属性突变告警 150 | 151 | 152 | ## 2.1.2(2017年2月16日) 153 | 154 | * 实现#12,GridItems上的按钮将触发移动设备上的拖动 155 | * 实现#24,在销毁之前删除监听 (感谢 [pbabey](https://github.com/pbabey)) 156 | 157 | 158 | ## 2.1.1(2017年2月9日) 159 | 160 | * 实现#13,支持行高动态更新 161 | * 实现#23,支持动态启用/禁用拖动和调整大小 162 | * 实现#21,移动并调整大小的事件 163 | 164 | 165 | ## 2.1.0(2017年2月6日) 166 | 167 | * RTL支持 (感谢 [easteregg](https://github.com/easteregg)) 168 | * 移动和调整事件大小 (感谢 [ThePlastic](https://github.com/ThePlastic)) 169 | -------------------------------------------------------------------------------- /website/docs/zh/guide/01-basic.md: -------------------------------------------------------------------------------- 1 | # 01 - 基本 2 | 3 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example01Basic.vue) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /website/docs/zh/guide/02-events.md: -------------------------------------------------------------------------------- 1 | # 02 - 移动事件并调整大小 2 | 3 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example02Events.vue) 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /website/docs/zh/guide/03-multiple-grids.md: -------------------------------------------------------------------------------- 1 | # 03 - 多个栅格 2 | 3 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example03MultipleGrids.vue) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /website/docs/zh/guide/04-allow-ignore.md: -------------------------------------------------------------------------------- 1 | # 04 - 拖动允许/忽略元素 2 | 3 | 忽略对某些元素的拖动而对其他元素的允许。 4 | 5 | 单击并拖动每个项目角上的点以重新定位 6 | 7 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example04AllowIgnore.vue) 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /website/docs/zh/guide/05-mirrored.md: -------------------------------------------------------------------------------- 1 | # 05 - 镜像反转栅格布局 2 | 3 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example05Mirrored.vue) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /website/docs/zh/guide/06-responsive.md: -------------------------------------------------------------------------------- 1 | # 06 - 响应式 2 | 3 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example06Responsive.vue) 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /website/docs/zh/guide/07-prevent-collision.md: -------------------------------------------------------------------------------- 1 | # 07 - 防止碰撞 2 | 3 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example07PreventCollision.vue) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /website/docs/zh/guide/08-responsive-predefined-layouts.md: -------------------------------------------------------------------------------- 1 | # 08 - 响应预定义的布局 2 | 3 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example08ResponsivePredefinedLayouts.vue) 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /website/docs/zh/guide/09-dynamic-add-remove.md: -------------------------------------------------------------------------------- 1 | # 09 - 动态添加/删除 2 | 3 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example09DynamicAddRemove.vue) 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /website/docs/zh/guide/10-drag-from-outside.md: -------------------------------------------------------------------------------- 1 | # 10 - 从外面拖动 2 | 3 | 该演示演示了从栅格外部添加部件时发生的情况。 4 |
5 | 将部件放到栅格中后,您将获得其坐标/属性,并可以据此执行操作。 6 | 7 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example10DragFromOutside.vue) 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /website/docs/zh/guide/11-bounded.md: -------------------------------------------------------------------------------- 1 | # 11 - 拖动栅格元素绑定到容器 2 | 3 | 可以获得栅格元素的坐标与容器间的绑定关系。 4 | 5 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/Example11Bounded.vue) 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /website/docs/zh/guide/README.md: -------------------------------------------------------------------------------- 1 | # 安装 2 | 3 | ## NPM 4 | 5 | npm install vue-grid-layout --save 6 | 7 | ## Yarn 8 | 9 | yarn add vue-grid-layout 10 | 11 | 12 | 导入库 13 | 14 | ```javascript 15 | import VueGridLayout from 'vue-grid-layout'; 16 | ``` 17 | 18 | 添加到其他Vue组件 19 | 20 | ```javascript 21 | export default { 22 | components: { 23 | GridLayout: VueGridLayout.GridLayout, 24 | GridItem: VueGridLayout.GridItem 25 | }, 26 | // ... data, methods, mounted (), etc. 27 | } 28 | 29 | ``` 30 | 31 | ## 浏览器 32 | 33 | 包括可用于浏览器的软件包([从发布版本](https://github.com/jbaysolutions/vue-grid-layout/releases)下载)。组件将自动可用。 34 | 35 | ```html 36 | 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /website/docs/zh/guide/auto-size.md: -------------------------------------------------------------------------------- 1 | # 自动调整栅格元素 2 | 3 | 待办: https://github.com/jbaysolutions/vue-grid-layout/issues/351 4 | -------------------------------------------------------------------------------- /website/docs/zh/guide/events.md: -------------------------------------------------------------------------------- 1 | # 事件 2 | 3 | 每一个栅格元素grid-item上都可以添加监听器,用于监听移动和调整大小事件,这样父级Vue对象就可以收到通知。 4 | 5 | 示例 [点击这里](../guide/02-events.md) 6 | 7 | ````html 8 | 9 | 25 | 26 | 38 | {{item.i}} 39 | 40 | 41 | ```` 42 | 43 | ## GridLayout 44 | 45 | ### layoutCreatedEvent 46 | 47 | 对应Vue生命周期的created 48 | 49 | ```javascript 50 | layoutCreatedEvent: function(newLayout){ 51 | console.log("Created layout: ", newLayout) 52 | } 53 | ``` 54 | 55 | ### layoutBeforeMountEvent 56 | 57 | 对应Vue生命周期的beforeMount 58 | 59 | ```javascript 60 | layoutBeforeMountEvent: function(newLayout){ 61 | console.log("beforeMount layout: ", newLayout) 62 | } 63 | ``` 64 | 65 | ### layoutMountedEvent 66 | 67 | 对应Vue生命周期的mounted 68 | 69 | ```javascript 70 | layoutMountedEvent: function(newLayout){ 71 | console.log("Mounted layout: ", newLayout) 72 | } 73 | ``` 74 | 75 | ### layoutReadyEvent 76 | 77 | 当完成mount中的所有操作时生成的事件 78 | 79 | ```javascript 80 | layoutReadyEvent: function(newLayout){ 81 | console.log("Ready layout: ", newLayout) 82 | } 83 | ``` 84 | 85 | ### layoutUpdatedEvent 86 | 87 | 布局updated事件 88 | 89 | 更新事件(布局更新或栅格元素的位置重新计算) 90 | 91 | ```javascript 92 | layoutUpdatedEvent: function(newLayout){ 93 | console.log("Updated layout: ", newLayout) 94 | } 95 | ``` 96 | 97 | 98 | ### breakpointChangedEvent 99 | 100 | 断点更改事件 101 | 102 | 每次断点值由于窗口调整大小而改变 103 | 104 | ```javascript 105 | /** 106 | * 107 | * @param newBreakpoint the breakpoint name 108 | * @param newLayout the chosen layout for the breakpoint 109 | * 110 | */ 111 | breakpointChangedEvent: function(newBreakpoint, newLayout){ 112 | console.log("BREAKPOINT CHANGED breakpoint=", newBreakpoint, ", layout: ", newLayout ); 113 | }, 114 | ``` 115 | 116 | 117 | ## GridItem 118 | 119 | ### moveEvent 120 | 121 | 移动时的事件 122 | 123 | ```javascript 124 | moveEvent: function(i, newX, newY){ 125 | console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY); 126 | }, 127 | ``` 128 | 129 | ### resizeEvent 130 | 131 | 调整大小时的事件 132 | 133 | ```javascript 134 | resizeEvent: function(i, newH, newW, newHPx, newWPx){ 135 | console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 136 | }, 137 | ``` 138 | 139 | ### movedEvent 140 | 141 | 移动后的事件 142 | 143 | ```javascript 144 | movedEvent: function(i, newX, newY){ 145 | console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY); 146 | }, 147 | ``` 148 | 149 | ### resizedEvent 150 | 151 | 调整大小后的事件 152 | 153 | ```javascript 154 | /** 155 | * 156 | * @param i the item id/index 157 | * @param newH new height in grid rows 158 | * @param newW new width in grid columns 159 | * @param newHPx new height in pixels 160 | * @param newWPx new width in pixels 161 | * 162 | */ 163 | resizedEvent: function(i, newH, newW, newHPx, newWPx){ 164 | console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 165 | }, 166 | ``` 167 | 168 | ### containerResizedEvent 169 | 170 | 栅格元素/栅格容器更改大小的事件(浏览器窗口或其他) 171 | 172 | 173 | ```javascript 174 | /** 175 | * 176 | * @param i the item id/index 177 | * @param newH new height in grid rows 178 | * @param newW new width in grid columns 179 | * @param newHPx new height in pixels 180 | * @param newWPx new width in pixels 181 | * 182 | */ 183 | containerResizedEvent: function(i, newH, newW, newHPx, newWPx){ 184 | console.log("CONTAINER RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 185 | }, 186 | ``` 187 | 188 | -------------------------------------------------------------------------------- /website/docs/zh/guide/examples.md: -------------------------------------------------------------------------------- 1 | # 例子 2 | 3 | ## 基本 4 | 5 | 6 | 7 | ## 事件 8 | 9 | 10 | 11 | ## 多个网格 12 | 13 | 14 | 15 | ## 拖动允许/忽略元素 16 | 17 | 忽略对某些元素的拖动,而对其他元素允许。 18 | 19 | 单击并拖动每个栅格角上的点以重新定位 20 | 21 | 22 | -------------------------------------------------------------------------------- /website/docs/zh/guide/properties.md: -------------------------------------------------------------------------------- 1 | # 属性 2 | 3 | ## GridLayout 4 | 5 | ### layout 6 | 7 | 8 | * type: `Array` 9 | * required: `true` 10 | 11 | 这是栅格的初始布局。 12 | 13 | 数据源。值必须为 `Array`,其数据项为 `Object`。 每条数据项必须有 `i, x, y, w 和 h` 属性。 请参考下面的 `GridItem`。 14 | 15 | ### responsiveLayouts 16 | 17 | * type: `Object` 18 | * required: `false` 19 | * default : `{}` 20 | 21 | 如果 `responsive` 设置为 `true`,该配置将作为栅格中每个断点的初始布局。键值是断点名称,每项的值都是类似 `layout` 属性定义的数据结构,值必须为 `Array`,其数据项为 `Object`。例如: `{lg: [layout items], md: [layout items]}`。需要注意的是,在创建栅格布局后设置该属性无效。 22 | 在创建GridLayout之后设置prop无效。 23 | 24 | 可以查看 [responsive](#responsive), [breakpoints](#breakpoints) 和 [cols](#cols) 25 | 26 | ### colNum 27 | 28 | * type: `Number` 29 | * required: `false` 30 | * default: `12` 31 | 32 | 定义栅格系统的列数,其值需为自然数。 33 | 34 | ### rowHeight 35 | 36 | * type: `Number` 37 | * required: `false` 38 | * default: `150` 39 | 40 | 每行的高度,单位像素。 41 | 42 | ### maxRows 43 | 44 | * type: `Number` 45 | * required: `false` 46 | * default: `Infinity` 47 | 48 | 定义最大行数。 49 | 50 | ### margin 51 | 52 | * type: `Array` 53 | * required: `false` 54 | * default: `[10, 10]` 55 | 56 | 定义栅格中的元素边距。 57 | 58 | 值必须是包含两个 `Number`的数组,数组中第一个元素表示水平边距,第二个表示垂直边距,单位为像素。 59 | 60 | ### isDraggable 61 | 62 | * type: `Boolean` 63 | * required: `false` 64 | * default: `true` 65 | 66 | 标识栅格中的元素是否可拖拽。 67 | 68 | ### isResizable 69 | 70 | * type: `Boolean` 71 | * required: `false` 72 | * default: `true` 73 | 74 | 标识栅格中的元素是否可调整大小。 75 | 76 | ### isMirrored 77 | 78 | * type: `Boolean` 79 | * required: `false` 80 | * default: `false` 81 | 82 | 标识栅格中的元素是否可镜像反转。 83 | 84 | ### autoSize 85 | 86 | * type: `Boolean` 87 | * required: `false` 88 | * default: `true` 89 | 90 | 标识容器是否自动调整大小。 91 | 92 | ### verticalCompact 93 | 94 | * type: `Boolean` 95 | * required: `false` 96 | * default: `true` 97 | 98 | 标识布局是否垂直压缩。 99 | 100 | ### preventCollision 101 | 102 | * type: `Boolean` 103 | * required: `false` 104 | * default: `false` 105 | 106 | 防止碰撞属性,值设置为`ture`时,栅格只能拖动至空白处。 107 | 108 | ### useCssTransforms 109 | 110 | * type: `Boolean` 111 | * required: `false` 112 | * default: `true` 113 | 114 | 标识是否使用CSS属性 `transition-property: transform;`。 115 | 116 | ### responsive 117 | 118 | * type: `Boolean` 119 | * required: `false` 120 | * default: `false` 121 | 122 | 标识布局是否为响应式。 123 | 124 | 可以查看 [responsiveLayouts](#responsivelayouts)、[breakpoints](#breakpoints)和 [cols](#cols) 125 | 126 | 127 | ### breakpoints 128 | 129 | * type: `Object` 130 | * required: `false` 131 | * default: { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 } 132 | 133 | 为响应式布局设置断点。 134 | 135 | 可以查看 [responsiveLayouts](#responsivelayouts) 和 [cols](#cols) 136 | 137 | ### cols 138 | 139 | * type: `Object` 140 | * required: `false` 141 | * default: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 } 142 | 143 | 设置每个断点对应的列数。 144 | 145 | ### useStyleCursor 146 | 147 | * type: `Boolean` 148 | * required: `false` 149 | * default: `true` 150 | 151 | 标识是否使用动态鼠标指针样式。当拖动出现卡顿时,将此值设为 `false`也许可以缓解布局问题。 152 | **此属性无效** 153 | 154 | ## GridItem 155 | 156 | ### i 157 | 158 | * type: `String` 159 | * required: `true` 160 | 161 | 栅格中元素的ID。 162 | 163 | ### x 164 | 165 | * type: `Number` 166 | * required: `true` 167 | 168 | 标识栅格元素位于第几列,需为自然数。 169 | 170 | ### y 171 | 172 | * type: `Number` 173 | * required: `true` 174 | 175 | 标识栅格元素位于第几行,需为自然数。 176 | 177 | ### w 178 | 179 | * type: `Number` 180 | * required: `true` 181 | 182 | 标识栅格元素的初始宽度,值为`colWidth`的倍数。 183 | 184 | ### h 185 | 186 | * type: `Number` 187 | * required: `true` 188 | 189 | 标识栅格元素的初始高度,值为`rowHeight`的倍数。 190 | 191 | ### minW 192 | 193 | * type: `Number` 194 | * required: `false` 195 | * default: `1` 196 | 197 | 栅格元素的最小宽度,值为`colWidth`的倍数。 198 | 199 | 如果`w`小于`minW`,则`minW`的值会被`w`覆盖。 200 | 201 | ### minH 202 | 203 | * type: `Number` 204 | * required: `false` 205 | * default: `1` 206 | 207 | 栅格元素的最小高度,值为`rowHeight`的倍数。 208 | 209 | 如果`h`小于`minH`,则`minH`的值会被h覆盖。 210 | 211 | ### maxW 212 | 213 | * type: `Number` 214 | * required: `false` 215 | * default: `Infinity` 216 | 217 | 栅格元素的最大宽度,值为`colWidth`的倍数。 218 | 219 | 如果`w`大于`maxW`,则`maxW`的值会被`w`覆盖。 220 | 221 | ### maxH 222 | 223 | * type: `Number` 224 | * required: `false` 225 | * default: `Infinity` 226 | 227 | 栅格元素的最大高度,值为`rowHeight`的倍数。 228 | 229 | 如果`h`大于`maxH`,则`maxH`的值会被`h`覆盖。 230 | 231 | ### isDraggable 232 | 233 | * type: `Boolean` 234 | * required: `false` 235 | * default: `null` 236 | 237 | 标识栅格元素是否可拖拽。如果值为`null`则取决于父容器。 238 | 239 | ### isResizable 240 | 241 | * type: `Boolean` 242 | * required: `false` 243 | * default: `null` 244 | 245 | 标识栅格元素是否可调整大小。如果值为`null`则取决于父容器。 246 | 247 | ### static 248 | 249 | * type: `Boolean` 250 | * required: `false` 251 | * default: `false` 252 | 253 | 标识栅格元素是否为静态的(无法拖拽、调整大小或被其他元素移动)。 254 | 255 | ### dragIgnoreFrom 256 | 257 | * type: `String` 258 | * required: `false` 259 | * default: `'a, button'` 260 | 261 | 标识栅格元素中哪些子元素无法触发拖拽事件,值为`css-like`选择器。 262 | 263 | 请参考[interact.js docs](http://interactjs.io/docs/#ignorable-selectors)中的`ignoreFrom`。 264 | 265 | ### dragAllowFrom 266 | 267 | * type: `String` 268 | * required: `false` 269 | * default: `null` 270 | 271 | 标识栅格元素中哪些子元素可以触发拖拽事件,值为`css-like`选择器。 272 | 273 | 如果值为`null`则表示所有子元素(`dragIgnoreFrom`的除外)。 274 | 275 | 请参考[interact.js docs](http://interactjs.io/docs/#ignorable-selectors)中的`allowFrom`。 276 | 277 | ### resizeIgnoreFrom 278 | 279 | * type: `String` 280 | * required: `false` 281 | * default: `'a, button'` 282 | 283 | 标识栅格元素中哪些子元素无法触发调整大小的事件,值为`css-like`选择器。 284 | 285 | 请参考[interact.js docs](http://interactjs.io/docs/#ignorable-selectors)中的`ignoreFrom`。 286 | -------------------------------------------------------------------------------- /website/docs/zh/guide/styling.md: -------------------------------------------------------------------------------- 1 | # 样式 2 | 3 | 可以定制栅格样式以适合您的需求。以下是可以覆盖的类的列表。 4 | 5 | ## 占位符 6 | 7 | 占位符的默认css为: 8 | 9 | ````css 10 | .vue-grid-item.vue-grid-placeholder { 11 | background: red; 12 | opacity: 0.2; 13 | transition-duration: 100ms; 14 | z-index: 2; 15 | -webkit-user-select: none; 16 | -moz-user-select: none; 17 | -ms-user-select: none; 18 | -o-user-select: none; 19 | user-select: none; 20 | } 21 | ```` 22 | 23 | 您可以使用`!important`规则覆盖属性: 24 | 25 | ````css 26 | .vue-grid-item.vue-grid-placeholder { 27 | background: green !important; 28 | } 29 | ```` 30 | 31 | 或者通过用更[具体的](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity)方式包装栅格类: 32 | 33 | ````css 34 | .container .vue-grid-item.vue-grid-placeholder { 35 | background: green; 36 | } 37 | ```` 38 | 39 | 在此示例中,我们将占位符的背景色更改为绿色: 40 | 41 | [查看资料](https://github.com/jbaysolutions/vue-grid-layout/blob/master/website/docs/.vuepress/components/ExampleStylingPlaceholder.vue) 42 | 43 | 44 | 45 | 46 | 47 | 48 | 工作正在进行中... 49 | -------------------------------------------------------------------------------- /website/docs/zh/guide/usage.md: -------------------------------------------------------------------------------- 1 | # 用法 2 | 3 | ```javascript 4 | new Vue({ 5 | el: '#app', 6 | data: { 7 | layout: [ 8 | {"x":0,"y":0,"w":2,"h":2,"i":"0"}, 9 | {"x":2,"y":0,"w":2,"h":4,"i":"1"}, 10 | {"x":4,"y":0,"w":2,"h":5,"i":"2"}, 11 | {"x":6,"y":0,"w":2,"h":3,"i":"3"}, 12 | {"x":8,"y":0,"w":2,"h":3,"i":"4"}, 13 | {"x":10,"y":0,"w":2,"h":3,"i":"5"}, 14 | {"x":0,"y":5,"w":2,"h":5,"i":"6"}, 15 | {"x":2,"y":5,"w":2,"h":5,"i":"7"}, 16 | {"x":4,"y":5,"w":2,"h":5,"i":"8"}, 17 | {"x":6,"y":3,"w":2,"h":4,"i":"9"}, 18 | {"x":8,"y":4,"w":2,"h":4,"i":"10"}, 19 | {"x":10,"y":4,"w":2,"h":4,"i":"11"}, 20 | {"x":0,"y":10,"w":2,"h":5,"i":"12"}, 21 | {"x":2,"y":10,"w":2,"h":5,"i":"13"}, 22 | {"x":4,"y":8,"w":2,"h":4,"i":"14"}, 23 | {"x":6,"y":8,"w":2,"h":4,"i":"15"}, 24 | {"x":8,"y":10,"w":2,"h":5,"i":"16"}, 25 | {"x":10,"y":4,"w":2,"h":2,"i":"17"}, 26 | {"x":0,"y":9,"w":2,"h":3,"i":"18"}, 27 | {"x":2,"y":6,"w":2,"h":2,"i":"19"} 28 | ], 29 | }, 30 | }); 31 | ``` 32 | 33 | 34 | ```html 35 | 36 | 47 | 48 | 55 | {{item.i}} 56 | 57 | 58 | ``` 59 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-grid-layout-website", 3 | "version": "1.0.0", 4 | "description": "vue-grid-layout website", 5 | "author": "Gustavo Santos (gustavo@jbaysolutions.com)", 6 | "license": "MIT", 7 | "private": false, 8 | "scripts": { 9 | "dev": "cross-env NODE_OPTIONS=--openssl-legacy-provider vuepress dev docs", 10 | "build": "vuepress build docs", 11 | "serve": "cross-env NODE_OPTIONS=--openssl-legacy-provider vuepress serve docs" 12 | }, 13 | "dependencies": { 14 | }, 15 | "devDependencies": { 16 | "cross-env": "^7.0.3", 17 | "@vuepress/plugin-back-to-top": "^1.9.9", 18 | "@vuepress/plugin-google-analytics": "^1.9.9", 19 | "vue-grid-layout": "^2.4.0", 20 | "vuepress-plugin-seo": "^0.1.4", 21 | "vuepress-plugin-sitemap": "^2.3.1", 22 | "vuepress": "^1.9.9", 23 | "vuepress-plugin-serve": "^2.0.4" 24 | }, 25 | "resolutions": { 26 | "watchpack": "1.6.1" 27 | } 28 | } 29 | --------------------------------------------------------------------------------