├── .editorconfig ├── .eslintignore ├── .eslintrc.cjs ├── .eslintrc.js ├── .github ├── CODE_OF_CONDUCT.md ├── FUNDING.yml ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .prettierrc.js ├── .stylelintignore ├── .stylelintrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── changelog.config.js ├── docs ├── Data Grid.svg ├── paypal-images │ ├── PNG │ │ ├── blue.png │ │ ├── dark.png │ │ └── grey.png │ ├── blue.svg │ ├── dark.svg │ └── grey.svg ├── setup.md ├── testing-package.md └── urls.txt ├── env.d.ts ├── index.html ├── package-lock.json ├── package.json ├── sandbox ├── App.vue ├── assets │ └── resize.svg ├── main.ts └── test.ts ├── src ├── assets │ ├── close.svg │ └── resize.svg ├── components │ ├── Grid │ │ ├── DragItem.vue │ │ ├── GridItem.vue │ │ ├── GridLayout.vue │ │ ├── grid-layout-props.interface.ts │ │ └── layout-definition.ts │ ├── common │ │ ├── CustomCloseButton.vue │ │ └── CustomDragElement.vue │ └── index.ts ├── core │ ├── common │ │ ├── enums │ │ │ ├── EMovingDirections.ts │ │ │ └── ErrorMessages.ts │ │ ├── helpers │ │ │ ├── breakpointsHelper.ts │ │ │ └── gridIemTypeHelpers.ts │ │ ├── interfaces │ │ │ ├── eventBus.interfaces.ts │ │ │ └── transformStyle.interfaces.ts │ │ └── types │ │ │ └── TMovingDirections.ts │ ├── griditem │ │ ├── enums │ │ │ └── EGridItemEvents.ts │ │ ├── helpers │ │ │ └── gridItemCalculateHelper.ts │ │ └── interfaces │ │ │ └── grid-item.interfaces.ts │ ├── gridlayout │ │ ├── enums │ │ │ ├── EDragEvent.ts │ │ │ └── EGridLayoutEvents.ts │ │ ├── helpers │ │ │ ├── collissionHelper.ts │ │ │ ├── gridLayoutHelper.ts │ │ │ ├── moveHelper.ts │ │ │ ├── responsiveHelper.ts │ │ │ └── sortHelper.ts │ │ └── interfaces │ │ │ └── layout-data.interface.ts │ ├── helpers │ │ ├── DOM.ts │ │ ├── calculateUtils.ts │ │ ├── draggableUtils.ts │ │ ├── layoutUtils.ts │ │ ├── point.interface.ts │ │ ├── responsiveUtils.ts │ │ └── utils.ts │ └── validators │ │ ├── breakpoint-validator.ts │ │ ├── keys-validator.ts │ │ ├── layout-validator.ts │ │ └── margin-validator.ts ├── hooks │ └── useInstance.ts ├── styles │ ├── index.scss │ └── variables.scss └── vite-env.d.ts ├── tests ├── breakpointValidator.spec.ts ├── breakpointsHelper.spec.ts ├── calculateUtils.spec.ts ├── collissionHelper.spec.ts ├── gridItemCalculateHelper.spec.ts ├── gridItemTypeHelpers.spec.ts ├── gridLayoutHelper.spec.ts ├── keyValidator.spec.ts ├── layoutValidator.spec.ts ├── marginValidator.spec.ts ├── moveHelper.spec.ts ├── sortHelper.spec.ts ├── testLayout.ts └── utils.spec.ts ├── tsconfig.build-types.json ├── tsconfig.config.json ├── tsconfig.json ├── vite.config.js ├── vitepress-docs ├── .vitepress │ ├── config.js │ ├── configs │ │ ├── nav.js │ │ └── sidebar.js │ ├── dist │ │ ├── 404.html │ │ ├── Data Grid.svg │ │ ├── api │ │ │ ├── GridItem-enums.html │ │ │ ├── GridLayout-enums.html │ │ │ ├── index.html │ │ │ ├── interfaces-eventBus.html │ │ │ ├── interfaces-layout.html │ │ │ └── types-layout.html │ │ ├── assets │ │ │ ├── api_GridItem-enums.md.CY87Ew73.js │ │ │ ├── api_GridItem-enums.md.CY87Ew73.lean.js │ │ │ ├── api_GridLayout-enums.md.CAP8d5La.js │ │ │ ├── api_GridLayout-enums.md.CAP8d5La.lean.js │ │ │ ├── api_index.md.C09OD24K.js │ │ │ ├── api_index.md.C09OD24K.lean.js │ │ │ ├── api_interfaces-eventBus.md.BoVerJx7.js │ │ │ ├── api_interfaces-eventBus.md.BoVerJx7.lean.js │ │ │ ├── api_interfaces-layout.md.BIyzYU9b.js │ │ │ ├── api_interfaces-layout.md.BIyzYU9b.lean.js │ │ │ ├── api_types-layout.md.DLhsXbwC.js │ │ │ ├── api_types-layout.md.DLhsXbwC.lean.js │ │ │ ├── app.y2ni2aWa.js │ │ │ ├── chunks │ │ │ │ ├── framework.DypzUre1.js │ │ │ │ ├── test.DiF0N8cN.js │ │ │ │ └── theme.9tTlfeSW.js │ │ │ ├── components_css-grid-item.md.DVqyfjrg.js │ │ │ ├── components_css-grid-item.md.DVqyfjrg.lean.js │ │ │ ├── components_css-grid-layout.md.OI24WuTh.js │ │ │ ├── components_css-grid-layout.md.OI24WuTh.lean.js │ │ │ ├── components_css-variables.md.COUjaV5E.js │ │ │ ├── components_css-variables.md.COUjaV5E.lean.js │ │ │ ├── components_grid-item-event-bus-events.md.C2MZog7y.js │ │ │ ├── components_grid-item-event-bus-events.md.C2MZog7y.lean.js │ │ │ ├── components_grid-item-events.md.C01h7Wp8.js │ │ │ ├── components_grid-item-events.md.C01h7Wp8.lean.js │ │ │ ├── components_grid-item-props.md.INyiBBAx.js │ │ │ ├── components_grid-item-props.md.INyiBBAx.lean.js │ │ │ ├── components_grid-item-slots.md.upPuBDGJ.js │ │ │ ├── components_grid-item-slots.md.upPuBDGJ.lean.js │ │ │ ├── components_grid-item.md.CPAgr0Y6.js │ │ │ ├── components_grid-item.md.CPAgr0Y6.lean.js │ │ │ ├── components_grid-layout-event-bus-events.md.CR5IuVtB.js │ │ │ ├── components_grid-layout-event-bus-events.md.CR5IuVtB.lean.js │ │ │ ├── components_grid-layout-events.md.BH8KhKvS.js │ │ │ ├── components_grid-layout-events.md.BH8KhKvS.lean.js │ │ │ ├── components_grid-layout-props.md.vNbBkqP9.js │ │ │ ├── components_grid-layout-props.md.vNbBkqP9.lean.js │ │ │ ├── components_grid-layout.md.CBRPOZKi.js │ │ │ ├── components_grid-layout.md.CBRPOZKi.lean.js │ │ │ ├── components_index.md.B3_E7yWG.js │ │ │ ├── components_index.md.B3_E7yWG.lean.js │ │ │ ├── examples_01-example.md.CpjcLeXb.js │ │ │ ├── examples_01-example.md.CpjcLeXb.lean.js │ │ │ ├── examples_02-example.md.xdK61rcG.js │ │ │ ├── examples_02-example.md.xdK61rcG.lean.js │ │ │ ├── examples_03-example.md.O0pf15mA.js │ │ │ ├── examples_03-example.md.O0pf15mA.lean.js │ │ │ ├── examples_04-example.md.B5gHf5UO.js │ │ │ ├── examples_04-example.md.B5gHf5UO.lean.js │ │ │ ├── examples_05-example.md.BVq1nHsn.js │ │ │ ├── examples_05-example.md.BVq1nHsn.lean.js │ │ │ ├── examples_06-example.md.zBUYEgBC.js │ │ │ ├── examples_06-example.md.zBUYEgBC.lean.js │ │ │ ├── examples_07-example.md.DkuN5EO6.js │ │ │ ├── examples_07-example.md.DkuN5EO6.lean.js │ │ │ ├── examples_08-example.md.oavXhDbg.js │ │ │ ├── examples_08-example.md.oavXhDbg.lean.js │ │ │ ├── examples_09-example.md.jwyUjZI3.js │ │ │ ├── examples_09-example.md.jwyUjZI3.lean.js │ │ │ ├── examples_10-example.md.i1jm-6wQ.js │ │ │ ├── examples_10-example.md.i1jm-6wQ.lean.js │ │ │ ├── examples_11-example.md.CHPw_daE.js │ │ │ ├── examples_11-example.md.CHPw_daE.lean.js │ │ │ ├── examples_12-example.md.Dd7bFAZb.js │ │ │ ├── examples_12-example.md.Dd7bFAZb.lean.js │ │ │ ├── examples_13-example.md.CTOGm0qH.js │ │ │ ├── examples_13-example.md.CTOGm0qH.lean.js │ │ │ ├── examples_14-example.md.DYMAMF7j.js │ │ │ ├── examples_14-example.md.DYMAMF7j.lean.js │ │ │ ├── examples_15-example.md.BeqmslxU.js │ │ │ ├── examples_15-example.md.BeqmslxU.lean.js │ │ │ ├── examples_16-example.md.BeSdN6RY.js │ │ │ ├── examples_16-example.md.BeSdN6RY.lean.js │ │ │ ├── features_index.md.AHctw1-D.js │ │ │ ├── features_index.md.AHctw1-D.lean.js │ │ │ ├── guide_changelog.md.gv5YiFNR.js │ │ │ ├── guide_changelog.md.gv5YiFNR.lean.js │ │ │ ├── guide_installation.md.BteGI3qK.js │ │ │ ├── guide_installation.md.BteGI3qK.lean.js │ │ │ ├── guide_introduction.md.BDS_NV86.js │ │ │ ├── guide_introduction.md.BDS_NV86.lean.js │ │ │ ├── guide_roadmap.md.9TcX4Dlx.js │ │ │ ├── guide_roadmap.md.9TcX4Dlx.lean.js │ │ │ ├── index.md.VCkZeN5U.js │ │ │ ├── index.md.VCkZeN5U.lean.js │ │ │ ├── inter-italic-cyrillic-ext.r48I6akx.woff2 │ │ │ ├── inter-italic-cyrillic.By2_1cv3.woff2 │ │ │ ├── inter-italic-greek-ext.1u6EdAuj.woff2 │ │ │ ├── inter-italic-greek.DJ8dCoTZ.woff2 │ │ │ ├── inter-italic-latin-ext.CN1xVJS-.woff2 │ │ │ ├── inter-italic-latin.C2AdPX0b.woff2 │ │ │ ├── inter-italic-vietnamese.BSbpV94h.woff2 │ │ │ ├── inter-roman-cyrillic-ext.BBPuwvHQ.woff2 │ │ │ ├── inter-roman-cyrillic.C5lxZ8CY.woff2 │ │ │ ├── inter-roman-greek-ext.CqjqNYQ-.woff2 │ │ │ ├── inter-roman-greek.BBVDIX6e.woff2 │ │ │ ├── inter-roman-latin-ext.4ZJIpNVo.woff2 │ │ │ ├── inter-roman-latin.Di8DUHzh.woff2 │ │ │ ├── inter-roman-vietnamese.BjW4sHH5.woff2 │ │ │ └── style.Dxsu8jvN.css │ │ ├── components │ │ │ ├── css-grid-item.html │ │ │ ├── css-grid-layout.html │ │ │ ├── css-variables.html │ │ │ ├── grid-item-event-bus-events.html │ │ │ ├── grid-item-events.html │ │ │ ├── grid-item-props.html │ │ │ ├── grid-item-slots.html │ │ │ ├── grid-item.html │ │ │ ├── grid-layout-event-bus-events.html │ │ │ ├── grid-layout-events.html │ │ │ ├── grid-layout-props.html │ │ │ ├── grid-layout.html │ │ │ └── index.html │ │ ├── examples │ │ │ ├── 01-example.html │ │ │ ├── 02-example.html │ │ │ ├── 03-example.html │ │ │ ├── 04-example.html │ │ │ ├── 05-example.html │ │ │ ├── 06-example.html │ │ │ ├── 07-example.html │ │ │ ├── 08-example.html │ │ │ ├── 09-example.html │ │ │ ├── 10-example.html │ │ │ ├── 11-example.html │ │ │ ├── 12-example.html │ │ │ ├── 13-example.html │ │ │ ├── 14-example.html │ │ │ ├── 15-example.html │ │ │ └── 16-example.html │ │ ├── features │ │ │ └── index.html │ │ ├── guide │ │ │ ├── changelog.html │ │ │ ├── installation.html │ │ │ ├── introduction.html │ │ │ └── roadmap.html │ │ ├── hashmap.json │ │ ├── index.html │ │ ├── logo.svg │ │ ├── npm-square-red.svg │ │ └── vp-icons.css │ └── theme │ │ ├── index.js │ │ └── styles │ │ └── index.css ├── api │ ├── GridItem-enums.md │ ├── GridLayout-enums.md │ ├── index.md │ ├── interfaces-eventBus.md │ ├── interfaces-layout.md │ └── types-layout.md ├── components │ ├── css-grid-item.md │ ├── css-grid-layout.md │ ├── css-variables.md │ ├── grid-item-event-bus-events.md │ ├── grid-item-events.md │ ├── grid-item-props.md │ ├── grid-item-slots.md │ ├── grid-item.md │ ├── grid-layout-event-bus-events.md │ ├── grid-layout-events.md │ ├── grid-layout-props.md │ ├── grid-layout.md │ └── index.md ├── examples │ ├── 01-example.md │ ├── 02-example.md │ ├── 03-example.md │ ├── 04-example.md │ ├── 05-example.md │ ├── 06-example.md │ ├── 07-example.md │ ├── 08-example.md │ ├── 09-example.md │ ├── 10-example.md │ ├── 11-example.md │ ├── 12-example.md │ ├── 13-example.md │ ├── 14-example.md │ ├── 15-example.md │ ├── 16-example.md │ └── components │ │ ├── 01-example.vue │ │ ├── 02-example.vue │ │ ├── 03-example.vue │ │ ├── 04-example.vue │ │ ├── 05-example.vue │ │ ├── 06-example.vue │ │ ├── 07-example.vue │ │ ├── 08-example.vue │ │ ├── 10-example.vue │ │ ├── 11-example.vue │ │ ├── 13-example.vue │ │ ├── 14-example.vue │ │ ├── 15-example.vue │ │ ├── 16-example.vue │ │ ├── test.ts │ │ └── test2.ts ├── features │ └── index.md ├── guide │ ├── changelog.md │ ├── installation.md │ ├── introduction.md │ └── roadmap.md ├── index.md └── public │ ├── Data Grid.svg │ ├── logo.svg │ └── npm-square-red.svg └── vitest.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | max_line_length = off 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | .editorconfig 2 | .eslintrc 3 | .eslintignore 4 | .gitignore 5 | .prettierrc 6 | .prettierignore 7 | .stylelintrc 8 | .stylelintignore 9 | cypress.config.ts 10 | package.json 11 | package-lock.json 12 | pnpm-lock.yaml 13 | tsconfig.json 14 | vite.config.ts 15 | vitest.config 16 | CHANGELOG.md 17 | README.md 18 | /.vscode 19 | /coverage 20 | /cypress 21 | /dist 22 | /docs 23 | /node_modules 24 | /src/vite-env.d.ts 25 | /tests 26 | /sandbox 27 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. 6 | 7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 8 | 9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. 10 | 11 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. 12 | 13 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) 14 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [gwinnem] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Expected Behavior 2 | 3 | Please describe the behavior you are expecting 4 | 5 | # Current Behavior 6 | 7 | What is the current behavior? 8 | 9 | # Failure Information (for bugs) 10 | 11 | Please help provide information about the failure if this is a bug. If it is not a bug, please remove the rest of this template. 12 | 13 | ## Steps to Reproduce 14 | 15 | Please provide detailed steps for reproducing the issue. 16 | 17 | 1. step 1 18 | 2. step 2 19 | 3. you get it... 20 | 21 | ## Context 22 | 23 | Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions. 24 | 25 | * Firmware Version: 26 | * Operating System: 27 | * SDK version: 28 | * Toolchain version: 29 | 30 | ## Failure Logs 31 | 32 | Please include any relevant log snippets or files here. 33 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. 4 | 5 | Fixes # (issue) 6 | 7 | # How Has This Been Tested? 8 | 9 | Please describe the tests that you ran to verify your changes. Please also note any relevant details for your test configuration. 10 | 11 | - [ ] Test A 12 | - [ ] Test B 13 | 14 | # Checklist: 15 | 16 | - [ ] My code follows the style guidelines of this project 17 | - [ ] I have performed a self-review of my own code 18 | - [ ] I have commented my code, particularly in hard-to-understand areas 19 | - [ ] I have made corresponding changes to the documentation 20 | - [ ] My changes generate no new warnings 21 | - [ ] Any dependent changes have been merged and published in downstream modules 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | /coverage 5 | /examples 6 | 7 | # vitepress 8 | /vitepress-docs/.vitepress/cache 9 | 10 | # coverage 11 | /tests/coverage 12 | 13 | # local env files 14 | .env.local 15 | .env.*.local 16 | 17 | # Log files 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | pnpm-debug.log* 22 | 23 | # Editor directories and files 24 | .idea 25 | .vscode 26 | *.suo 27 | *.ntvs* 28 | *.njsproj 29 | *.sln 30 | *.sw? 31 | 32 | # npm package 33 | /vue-ts-responsive-grid-layout*.tgz 34 | vue-ts-responsive-grid-layout*.tgz 35 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .editorconfig 2 | .eslintrc 3 | .eslintignore 4 | .gitignore 5 | .husky 6 | .prettierrc 7 | .prettierignore 8 | .stylelintrc 9 | .vscode/ 10 | cypress.config.ts 11 | package.json 12 | package-lock.json 13 | pnpm-lock.yaml 14 | tsconfig.json 15 | vite.config.ts 16 | CHANGELOG.md 17 | README.md 18 | TODO.md 19 | coverage/ 20 | cypress/ 21 | dist/ 22 | docs/ 23 | node_modules/ 24 | public/assets/ 25 | src/vite-env.d.ts 26 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true, 6 | "quoteProps": "as-needed", 7 | "trailingComma": "all", 8 | "bracketSpacing": true, 9 | "arrowParens": "always", 10 | "printWidth": 120, 11 | "endOfLine": "auto", 12 | "vueIndentScriptAndStyle": true, 13 | "overrides": [ 14 | { 15 | "files": ["*.json"], 16 | "options": { 17 | "printWidth": 80 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true, 6 | "quoteProps": "as-needed", 7 | "trailingComma": "all", 8 | "bracketSpacing": true, 9 | "arrowParens": "always", 10 | "printWidth": 120, 11 | "endOfLine": "auto", 12 | "vueIndentScriptAndStyle": true, 13 | "bracketSpacing": false, 14 | "overrides": [ 15 | { 16 | "files": [ 17 | "*.json" 18 | ], 19 | "options": { 20 | "printWidth": 80 21 | } 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | /coverage/* 2 | /cyprus/* 3 | /docs/* 4 | /dist/* 5 | /node_modules/* 6 | /sandbox/* 7 | /tests/* 8 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "stylelint-config-standard-scss", 4 | "stylelint-config-recommended-vue/scss", 5 | "stylelint-config-html/vue" 6 | ], 7 | "plugins": [ 8 | "stylelint-order" 9 | ], 10 | "rules": { 11 | "at-rule-name-case": null, 12 | "at-rule-no-unknown": null, 13 | "comment-empty-line-before": null, 14 | "declaration-block-no-redundant-longhand-properties": true, 15 | "function-no-unknown": [true, { 16 | "ignoreFunctions": ["/color/", "/string/", "/v-bind/"] 17 | }], 18 | "media-feature-name-case": null, 19 | "media-feature-name-no-unknown": null, 20 | "no-descending-specificity": null, 21 | "no-duplicate-selectors": true, 22 | "no-empty-source": null, 23 | "no-extra-semicolons": true, 24 | "no-invalid-double-slash-comments": null, 25 | "number-leading-zero": "never", 26 | "order/properties-alphabetical-order": true, 27 | "scss/at-import-partial-extension": null, 28 | "scss/at-import-partial-extension-blacklist": ["scss"], 29 | "scss/dollar-variable-colon-space-before": null, 30 | "scss/dollar-variable-empty-line-before": null, 31 | "selector-class-pattern": [ 32 | "^([a-z][a-z0-9]*)(-[a-z0-9]+)*((__[a-z0-9-]+)?((--[a-z0-9]+)?(-[a-z0-9]+)*))$", 33 | { "message": "Expected class selector to be BEM" } 34 | ], 35 | "selector-pseudo-element-colon-notation": null, 36 | "selector-pseudo-element-no-unknown": null, 37 | "shorthand-property-no-redundant-values": null, 38 | "string-quotes": "single", 39 | "value-keyword-case": ["lower", { 40 | "ignoreFunctions": ["/^v-bind$/"] 41 | }] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2023 Geirr Winnem 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 | -------------------------------------------------------------------------------- /changelog.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | disableEmoji: false, 3 | format: '{type}{scope}: {emoji}{subject}', 4 | list: ['test', 'feat', 'fix', 'chore', 'docs', 'refactor', 'style', 'ci', 'perf'], 5 | maxMessageLength: 64, 6 | minMessageLength: 3, 7 | questions: ['type', 'scope', 'subject', 'body', 'breaking', 'issues', 'lerna'], 8 | scopes: [], 9 | types: { 10 | chore: { 11 | description: 'Build process or auxiliary tool changes', 12 | emoji: '🤖', 13 | value: 'chore' 14 | }, 15 | ci: { 16 | description: 'CI related changes', 17 | emoji: '🎡', 18 | value: 'ci' 19 | }, 20 | docs: { 21 | description: 'Documentation only changes', 22 | emoji: '✏️', 23 | value: 'docs' 24 | }, 25 | feat: { 26 | description: 'A new feature', 27 | emoji: '🎸', 28 | value: 'feat' 29 | }, 30 | fix: { 31 | description: 'A bug fix', 32 | emoji: '🐛', 33 | value: 'fix' 34 | }, 35 | perf: { 36 | description: 'A code change that improves performance', 37 | emoji: '⚡️', 38 | value: 'perf' 39 | }, 40 | refactor: { 41 | description: 'A code change that neither fixes a bug or adds a feature', 42 | emoji: '💡', 43 | value: 'refactor' 44 | }, 45 | release: { 46 | description: 'Create a release commit', 47 | emoji: '🏹', 48 | value: 'release' 49 | }, 50 | style: { 51 | description: 'Markup, white-space, formatting, missing semi-colons...', 52 | emoji: '💄', 53 | value: 'style' 54 | }, 55 | test: { 56 | description: 'Adding missing tests', 57 | emoji: '💍', 58 | value: 'test' 59 | }, 60 | messages: { 61 | type: 'Select the type of change that you\'re committing:', 62 | customScope: 'Select the scope this component affects:', 63 | subject: 'Write a short, imperative mood description of the change:\n', 64 | body: 'Provide a longer description of the change:\n ', 65 | breaking: 'List any breaking changes:\n', 66 | footer: 'Issues this commit closes, e.g #123:', 67 | confirmCommit: 'The packages that this commit has affected\n', 68 | }, 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /docs/Data Grid.svg: -------------------------------------------------------------------------------- 1 | 2 | Icons8 RSL Colored Part 10 3 | -------------------------------------------------------------------------------- /docs/paypal-images/PNG/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/docs/paypal-images/PNG/blue.png -------------------------------------------------------------------------------- /docs/paypal-images/PNG/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/docs/paypal-images/PNG/dark.png -------------------------------------------------------------------------------- /docs/paypal-images/PNG/grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/docs/paypal-images/PNG/grey.png -------------------------------------------------------------------------------- /docs/setup.md: -------------------------------------------------------------------------------- 1 | ## Setting up vue-ts-responsive-grid-layout in your project 2 | 3 | #### Installing external dependencies 4 | ``` 5 | npm install 6 | ``` 7 | 8 |
9 | 10 | #### Compiles and hot-reloads for development 11 | ``` 12 | npm run dev 13 | ``` 14 | 15 |
16 | 17 | #### Uses Vite to build our component library (compiles .vue files to .js) and call build:types script & npm pack. 18 | ``` 19 | npm run build 20 | ``` 21 | 22 |
23 | 24 | #### Generate TypeScript declaration files for our .vue files (this is using vue-tsc). 25 | ``` 26 | npm run build:types 27 | ``` 28 | 29 |
30 | 31 | #### Running type checking on .ts files (this is using vue-tsc). 32 | ``` 33 | npm run typeCheck 34 | ``` 35 | 36 |
37 | 38 | #### Running Eslint 39 | ``` 40 | npm run lint 41 | ``` 42 | 43 |
44 | 45 | #### Running Eslint with --fix option 46 | ``` 47 | npm run lint:fix 48 | ``` 49 | 50 |
51 | 52 | #### Running Style linting 53 | ``` 54 | npm run lint:style 55 | ``` 56 | -------------------------------------------------------------------------------- /docs/testing-package.md: -------------------------------------------------------------------------------- 1 | # How to test the npm package before publishing it: 2 | 3 | Before you publish the package it is a good idea to test it. 4 | To do this you can use npm pack to create .tgz file. 5 | This file can be imported in another project to test the package. 6 | You can use the package by copying the .tgz file to the other project, 7 | and running the following commands: 8 | 9 | ``` 10 | npm pack 11 | ``` 12 | 13 |
14 | 15 | ``` 16 | npm install vue-ts-responsive-grid-layout.tgz 17 | ``` 18 | 19 | Where vue-ts-responsive-grid-layout is the name of your package. 20 | -------------------------------------------------------------------------------- /docs/urls.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/docs/urls.txt -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vue3 Responsive Grid Layout 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-ts-responsive-grid-layout", 3 | "version": "1.2.10", 4 | "type": "module", 5 | "description": "Vue 3 Responsive & Dynamic Grid / Dashboard layout with drag, drop and resizable actions.", 6 | "author": "Geirr Winnem ", 7 | "contributors": [ 8 | { 9 | "name": "UTing1119", 10 | "url": "https://github.com/UTing1119" 11 | }, 12 | { 13 | "name": "T0miii", 14 | "url": "https://github.com/T0miii" 15 | } 16 | ], 17 | "funding": { 18 | "type": "paypal", 19 | "url": "https://paypal.me/gwinnem" 20 | }, 21 | "license": "MIT", 22 | "keywords": [ 23 | "grid", 24 | "dynamic-grid", 25 | "grid-layout", 26 | "responsive-grid-layout", 27 | "dynamic-grid-layout", 28 | "layout", 29 | "resize", 30 | "drag", 31 | "drop", 32 | "drag-and-drop", 33 | "responsive", 34 | "typescript", 35 | "es6", 36 | "vue-plugin", 37 | "vite", 38 | "vue-3", 39 | "composition-api", 40 | "vue-component-library", 41 | "dashboard", 42 | "dashboard-layout", 43 | "dashboard-responsive-layout", 44 | "dynamic-dashboard" 45 | ], 46 | "main": "dist/vue-ts-responsive-grid-layout.umd.js", 47 | "module": "vue-ts-responsive-grid-layout.es.js", 48 | "typeings": "./dist/types/components/index.d.ts", 49 | "files": [ 50 | "dist/*" 51 | ], 52 | "sideEffects": false, 53 | "exports": { 54 | ".": { 55 | "import": "./dist/vue-ts-responsive-grid-layout.es.js", 56 | "require": "./dist/vue-ts-responsive-grid-layout.umd.js" 57 | }, 58 | "./style.css": "./dist/style.css" 59 | }, 60 | "homepage": "https://vue-ts-responsive-grid-layout.winnem.tech", 61 | "repository": { 62 | "type": "git", 63 | "url": "git+https://github.com/gwinnem/vue-responsive-grid-layout.git" 64 | }, 65 | "bugs": { 66 | "url": "https://github.com/gwinnem/vue-responsive-grid-layout/issues" 67 | }, 68 | "scripts": { 69 | "dev": "vite", 70 | "coverage": "vitest run --coverage", 71 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", 72 | "commit": "cz", 73 | "commit:init": "commitizen init cz-conventional-changelog --save-dev --save-exact", 74 | "build:all": "vite build && npm run build:types && npm pack", 75 | "build:only": "vite build", 76 | "build:types": "vue-tsc --project tsconfig.json --declaration --emitDeclarationOnly --outDir ./dist", 77 | "typecheck": "vue-tsc --project tsconfig.json --noEmit", 78 | "lint": "eslint \"src/**/*.{js,ts,vue}\" --color", 79 | "lint:fix": "eslint \"src/**/*.{js,ts,vue}\" --fix --color", 80 | "lint:style": "npx stylelint src/**/*.{scss,vue} --no-fix --color", 81 | "lint:style-fix": "npx stylelint src/**/*.{scss,vue} --fix --color", 82 | "lint:markup": "vue-tsc -noEmit", 83 | "format": "prettier -w -u .", 84 | "test": "vitest", 85 | "test:ui": "vitest --ui", 86 | "test:coverage": "vitest run --coverage", 87 | "docs:dev": "vitepress dev vitepress-docs", 88 | "docs:build": "vitepress build vitepress-docs", 89 | "docs:preview": "vitepress preview vitepress-docs" 90 | }, 91 | "dependencies": { 92 | "@interactjs/actions": "^1.10.17", 93 | "@interactjs/auto-scroll": "^1.10.17", 94 | "@interactjs/auto-start": "^1.10.17", 95 | "@interactjs/interactjs": "^1.10.17", 96 | "@interactjs/modifiers": "^1.10.17", 97 | "element-resize-detector": "^1.2.4", 98 | "mitt": "^3.0.1" 99 | }, 100 | "devDependencies": { 101 | "@babel/types": "^7.27.0", 102 | "@interactjs/dev-tools": "^1.10.17", 103 | "@interactjs/types": "^1.10.27", 104 | "@types/element-resize-detector": "^1.1.6", 105 | "@types/node": "^22.15.2", 106 | "@typescript-eslint/eslint-plugin": "^8.31.0", 107 | "@typescript-eslint/parser": "^8.31.0", 108 | "@vitejs/plugin-vue": "^5.2.3", 109 | "@vitest/coverage-v8": "^3.1.2", 110 | "@vitest/ui": "^3.1.2", 111 | "@vue/compiler-sfc": "^3.5.13", 112 | "@vue/theme": "^2.3.0", 113 | "@vue/tsconfig": "^0.7.0", 114 | "cross-env": "^7.0.3", 115 | "cz-conventional-changelog": "^3.3.0", 116 | "eslint": "^9.25.1", 117 | "eslint-plugin-import": "^2.31.0", 118 | "eslint-plugin-import-quotes": "^0.0.1", 119 | "eslint-plugin-prettier": "^5.2.6", 120 | "eslint-plugin-vue": "^10.0.0", 121 | "husky": "^9.1.7", 122 | "jsdom": "^26.1.0", 123 | "lint-staged": "^15.5.1", 124 | "path": "^0.12.7", 125 | "postcss": "^8.5.3", 126 | "postcss-html": "^1.8.0", 127 | "postcss-scss": "^4.0.9", 128 | "prettier": "^3.5.3", 129 | "sass": "^1.87.0", 130 | "sass-loader": "^16.0.5", 131 | "scss": "^0.2.4", 132 | "stylelint": "^16.19.1", 133 | "stylelint-config-recommended-scss": "^14.1.0", 134 | "stylelint-config-recommended-vue": "^1.6.0", 135 | "stylelint-config-standard-scss": "^14.0.0", 136 | "stylelint-order": "^7.0.0", 137 | "ttypescript": "^2.5.2", 138 | "typescript": "^5.8.3", 139 | "unplugin-vue-markdown": "^28.3.1", 140 | "vite": "^6.3.3", 141 | "vite-plugin-dts": "^4.5.3", 142 | "vitepress": "^1.6.3", 143 | "vitest": "^3.1.2", 144 | "vue": "^3.2.0", 145 | "vue-eslint-parser": "^10.1.3", 146 | "vue-multiselect": "^3.2.0", 147 | "vue-ts-responsive-grid-layout": "^1.2.10", 148 | "vue-tsc": "^2.2.10" 149 | }, 150 | "husky": { 151 | "hooks": { 152 | "pre-commit": "lint-staged" 153 | } 154 | }, 155 | "lint-staged": { 156 | "*.{ts,vue}": "eslint --fix", 157 | "*.{css,scss,vue}": "stylelint --fix", 158 | "*": "prettier -w -u" 159 | }, 160 | "browserslist": [ 161 | "> 1%", 162 | "last 2 versions", 163 | "not dead" 164 | ], 165 | "peerDependencies": { 166 | "vue": "^3.0.0" 167 | }, 168 | "engines": { 169 | "node": ">= 14.18.0" 170 | }, 171 | "config": { 172 | "commitizen": { 173 | "path": "cz-emoji" 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /sandbox/assets/resize.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sandbox/main.ts: -------------------------------------------------------------------------------- 1 | import App from './App.vue' 2 | import { createApp } from 'vue' 3 | 4 | const app = createApp(App) 5 | 6 | app.mount('#app') 7 | 8 | -------------------------------------------------------------------------------- /sandbox/test.ts: -------------------------------------------------------------------------------- 1 | import {TLayout} from '@/components/Grid/layout-definition'; 2 | 3 | export const testData: TLayout = [ 4 | // test 1 5 | { 6 | i: 1, 7 | h: 2, 8 | w: 1, 9 | x: 0, 10 | y: 0, 11 | isDraggable: true, 12 | isResizable: false, 13 | }, 14 | { 15 | i: 2, 16 | h: 1, 17 | w: 2, 18 | x: 1, 19 | y: 0 20 | }, 21 | { 22 | i: 3, 23 | h: 2, 24 | w: 1, 25 | x: 2, 26 | y: 1 27 | }, 28 | { 29 | i: 4, 30 | h: 2, 31 | w: 1, 32 | x: 3, 33 | y: 1, 34 | isStatic: true 35 | }, 36 | { 37 | i: 5, 38 | h: 2, 39 | w: 1, 40 | x: 4, 41 | y: 0 42 | }, 43 | { 44 | i: 6, 45 | h: 1, 46 | w: 1, 47 | x: 5, 48 | y: 0, 49 | isStatic: true 50 | }, 51 | { 52 | i: 7, 53 | h: 3, 54 | w: 1, 55 | x: 0, 56 | y: 2, 57 | isDraggable: false, 58 | isResizable: false, 59 | }, 60 | { 61 | i: 8, 62 | h: 1, 63 | w: 1, 64 | x: 1, 65 | y: 1, 66 | isStatic: true 67 | }, 68 | 69 | // test 2 70 | // { h: 1, i: 1, w: 1, x: 0, y: 0 }, 71 | // { h: 1, i: 2, w: 1, x: 1, y: 0 }, 72 | // { h: 1, i: 3, w: 1, x: 2, y: 0 }, 73 | // { h: 1, i: 4, w: 1, x: 3, y: 0 }, 74 | // { h: 1, i: 5, w: 1, x: 4, y: 0 }, 75 | // { h: 1, i: 6, w: 1, x: 0, y: 0 }, 76 | // { h: 1, i: 7, w: 1, x: 1, y: 0 }, 77 | // { h: 1, i: 8, w: 1, x: 2, y: 0 }, 78 | 79 | // test 3 80 | // { x:0, y:0, w:2, h:2, i:0, isDraggable: false }, 81 | // { x:2, y:0, w:2, h:2, i:1, isStatic: true }, 82 | // { x:4, y:0, w:2, h:2, i:2, isResizable: false }, 83 | // { x:0, y:2, w:2, h:2, i:3 }, 84 | // { x:2, y:2, w:2, h:2, i:4 }, 85 | // { x:4, y:2, w:2, h:2, i:5 }, 86 | // { x:0, y:4, w:2, h:2, i:6 }, 87 | // { x:2, y:4, w:2, h:2, i:7 }, 88 | // { x:4, y:4, w:2, h:2, i:8 }, 89 | // { x:0, y:6, w:2, h:2, i:9 }, 90 | // { x:2, y:6, w:2, h:2, i:10 }, 91 | // { x:4, y:6, w:2, h:2, i:11 }, 92 | 93 | // test 4 94 | // { h: 1, i: 1, w: 1, x: 0, y: 0 }, 95 | // { h: 1, i: 2, w: 1, x: 1, y: 0 }, 96 | // { h: 1, i: 3, w: 1, x: 2, y: 0 }, 97 | // { h: 1, i: 4, w: 1, x: 3, y: 0 }, 98 | // { h: 1, i: 5, w: 2, x: 4, y: 0 }, 99 | // { h: 4, i: 6, w: 4, x: 0, y: 1 }, 100 | // { h: 2, i: 7, w: 2, x: 4, y: 1 }, 101 | // { h: 2, i: 8, w: 2, x: 4, y: 3 }, 102 | ]; 103 | 104 | export const testDataOne: TLayout = [ 105 | // test 1 106 | { 107 | i: 1, 108 | h: 2, 109 | w: 1, 110 | x: 0, 111 | y: 0, 112 | }, 113 | { 114 | i: 2, 115 | h: 2, 116 | w: 1, 117 | x: 1, 118 | y: 0, 119 | }, 120 | { 121 | i: 3, 122 | h: 2, 123 | w: 1, 124 | x: 2, 125 | y: 0, 126 | isStatic: false, 127 | }, 128 | { 129 | i: 4, 130 | h: 2, 131 | w: 1, 132 | x: 3, 133 | y: 0, 134 | }, 135 | { 136 | i: 5, 137 | h: 2, 138 | w: 1, 139 | x: 4, 140 | y: 0, 141 | }, 142 | { 143 | i: 6, 144 | h: 2, 145 | w: 1, 146 | x: 5, 147 | y: 0, 148 | }, 149 | { 150 | i: 7, 151 | h: 2, 152 | w: 1, 153 | x: 6, 154 | y: 0, 155 | }, 156 | { 157 | i: 8, 158 | h: 2, 159 | w: 1, 160 | x: 7, 161 | y: 0, 162 | } 163 | ] 164 | 165 | export const testDataTwo: TLayout = [ 166 | { 167 | i: 'test', 168 | h: 2, 169 | w: 1, 170 | x: 2, 171 | y: 0, 172 | isDraggable: true, 173 | isResizable: true, 174 | }, 175 | ] 176 | 177 | export const testDataThree = [ 178 | { 179 | "name": "TaskOpener", 180 | "widgetId": "taskopener-0", 181 | "i": "0", 182 | "x": 0, 183 | "y": 0, 184 | "w": 1, 185 | "h": 3, 186 | "collapsed": false, 187 | "isResizable": false, 188 | "moved": false 189 | }, 190 | { 191 | "name": "PostTask", 192 | "widgetId": "posttask-1", 193 | "i": "1", 194 | "x": 0, 195 | "y": 8, 196 | "w": 1, 197 | "h": 8, 198 | "collapsed": false, 199 | "moved": false, 200 | "_h": 8 201 | }, 202 | { 203 | "i": "6", 204 | "x": 0, 205 | "y": 3, 206 | "w": 1, 207 | "h": 2, 208 | "name": "CaseManager", 209 | "widgetId": "casemanager-5", 210 | "collapsed": true, 211 | "moved": false, 212 | "_h": 8 213 | }, 214 | { 215 | "i": "8", 216 | "x": 0, 217 | "y": 5, 218 | "w": 1, 219 | "h": 3, 220 | "name": "CaseManager", 221 | "widgetId": "casemanager-7", 222 | "collapsed": true, 223 | "_h": 8, 224 | "moved": false 225 | }, 226 | { 227 | "i": "9", 228 | "x": 0, 229 | "y": 16, 230 | "name": "AddWidget", 231 | "widgetId": "addwidget", 232 | "w": 1, 233 | "h": 2, 234 | "isResizable": false, 235 | "moved": false 236 | } 237 | ] 238 | -------------------------------------------------------------------------------- /src/assets/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/resize.svg: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/components/Grid/grid-layout-props.interface.ts: -------------------------------------------------------------------------------- 1 | import { TLayout } from '@/components/Grid/layout-definition'; 2 | 3 | export interface IBreakpoints { 4 | xxl: number; 5 | xl: number; 6 | lg: number; 7 | md: number; 8 | sm: number; 9 | xs: number; 10 | xxs: number; 11 | } 12 | 13 | export interface IColumns { 14 | xxl: number; 15 | xl: number; 16 | lg: number; 17 | md: number; 18 | sm: number; 19 | xs: number; 20 | xxs: number; 21 | } 22 | 23 | export interface IGridLayoutProps { 24 | autoSize?: boolean; 25 | borderRadiusPx?: number; 26 | breakpoints?: IBreakpoints; 27 | colNum?: number; 28 | cols?: IColumns; 29 | distributeEvenly?: boolean; 30 | horizontalShift?: boolean; 31 | isBounded?: boolean; 32 | isDraggable?: boolean; 33 | isMirrored?: boolean; 34 | isResizable?: boolean; 35 | layout: TLayout; 36 | margin?: number[]; 37 | maxRows?: number; 38 | preventCollision?: boolean; 39 | responsive?: boolean; 40 | responsiveLayouts?: { [key: string]: TLayout }; 41 | restoreOnDrag?: boolean; 42 | rowHeight?: number; 43 | showCloseButton?: boolean; 44 | showGridLines?: boolean; 45 | transformScale?: number; 46 | useBorderRadius?: boolean; 47 | useCssTransforms?: boolean; 48 | verticalCompact?: boolean; 49 | } 50 | -------------------------------------------------------------------------------- /src/components/Grid/layout-definition.ts: -------------------------------------------------------------------------------- 1 | export interface ILayoutItemRequired { 2 | i: string | number; 3 | h: number; 4 | w: number; 5 | x: number; 6 | y: number; 7 | } 8 | 9 | export interface ILayoutItem extends ILayoutItemRequired { 10 | isDraggable?: boolean; 11 | isResizable?: boolean; 12 | isStatic?: boolean; 13 | maxH?: number; 14 | maxW?: number; 15 | minH?: number; 16 | minW?: number; 17 | moved?: boolean; 18 | } 19 | 20 | export type TLayoutItem = ILayoutItemRequired & { 21 | isDraggable?: boolean; 22 | isResizable?: boolean; 23 | isStatic?: boolean; 24 | maxH?: number; 25 | maxW?: number; 26 | minH?: number; 27 | minW?: number; 28 | moved?: boolean; 29 | } 30 | 31 | export type TLayout = ILayoutItem[]; 32 | 33 | export type TResponsiveLayout = { 34 | xxl?: TLayout; 35 | xl?: TLayout; 36 | lg?: TLayout; 37 | md?: TLayout; 38 | sm?: TLayout; 39 | xs?: TLayout; 40 | xxs?: TLayout; 41 | }; 42 | 43 | export type TBreakpoint = string; 44 | 45 | export type TBreakpoints = { 46 | xxl?: number; 47 | xl?: number; 48 | lg?: number; 49 | md?: number; 50 | sm?: number; 51 | xs?: number; 52 | xxs?: number; 53 | }; 54 | -------------------------------------------------------------------------------- /src/components/common/CustomCloseButton.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 32 | 33 | 99 | -------------------------------------------------------------------------------- /src/components/common/CustomDragElement.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 19 | 20 | 35 | -------------------------------------------------------------------------------- /src/components/index.ts: -------------------------------------------------------------------------------- 1 | import GridItem from './Grid/GridItem.vue'; 2 | import GridLayout from './Grid/GridLayout.vue'; 3 | import CustomCloseButton from './common/CustomCloseButton.vue'; 4 | import CustomDragElement from './common/CustomDragElement.vue'; 5 | import { 6 | ILayoutItem, 7 | TLayout, 8 | TResponsiveLayout, 9 | } from './Grid/layout-definition'; 10 | 11 | import { EGridItemEvent } from '@/core/griditem/enums/EGridItemEvents'; 12 | 13 | export { 14 | CustomCloseButton, 15 | CustomDragElement, 16 | GridItem, 17 | GridLayout, 18 | }; 19 | 20 | export type { 21 | EGridItemEvent, 22 | ILayoutItem, 23 | TLayout, 24 | TResponsiveLayout, 25 | }; 26 | -------------------------------------------------------------------------------- /src/core/common/enums/EMovingDirections.ts: -------------------------------------------------------------------------------- 1 | export enum EMovingDirections { 2 | DOWN = `DOWN`, 3 | LEFT = `LEFT`, 4 | RIGHT = `RIGHT`, 5 | UP = `UP`, 6 | } 7 | -------------------------------------------------------------------------------- /src/core/common/enums/ErrorMessages.ts: -------------------------------------------------------------------------------- 1 | export enum ErrorMsg { 2 | INVALID_BREAKPOINT = 'Invalid parameter breakpoint', 3 | INVALID_BREAKPOINT_NOT_FOUND = 'Breakpoint not found', 4 | INVALID_BOUNDS = 'Invalid parameter bounds passed', 5 | INVALID_COL_OR_ROW_SIZE = 'Invalid colOrRowSize parameter passed', 6 | INVALID_COLUMNS = 'Invalid parameter cols passed', 7 | INVALID_EMPTY_LAYOUT = 'Layout can not be empty', 8 | INVALID_GRID_UNITS = 'Invalid gridUnits parameter passed', 9 | INVALID_LAYOUT = 'Invalid parameter layout passed', 10 | INVALID_LAYOUT_ITEM = 'Invalid parameter layoutItem passed', 11 | INVALID_LAYOUT_ITEM_ID = 'Invalid parameter layoutItem id passed', 12 | INVALID_LAYOUT_VALIDATED = 'Layout is not valid', 13 | INVALID_MARGIN = 'Invalid marginPx parameter passed', 14 | INVALID_MARGIN_LEFT_RIGHT = 'Invalid parameter marginLeftRight passed', 15 | INVALID_PARAM_COLS = 'Parameter cols must be greater than 0', 16 | INVALID_PARAM_CONTAINER_WIDTH = 'Invalid parameter containerWidth passed', 17 | INVALID_PARAM_INNER_H = 'Parameter innerH must be greater than 0', 18 | INVALID_PARAM_INNER_W = 'Parameter innerW must be greater than 0', 19 | INVALID_PARAM_MARGIN = 'Parameter margin must be greater than 0', 20 | INVALID_PARAM_MAX_ROWS = 'Parameter maxRows must be greater than 0', 21 | INVALID_PARAM_ROW_HEIGHT = 'Parameter rowHeight must be greater than 0', 22 | INVALID_PARAMS = 'Invalid parameter values passed', 23 | INVALID_WIDTH = 'Width must be greater that 0', 24 | } 25 | -------------------------------------------------------------------------------- /src/core/common/helpers/breakpointsHelper.ts: -------------------------------------------------------------------------------- 1 | import { TBreakpoint, TBreakpoints } from '@/components/Grid/layout-definition'; 2 | import { IColumns } from '@/components/Grid/grid-layout-props.interface'; 3 | import { ErrorMsg } from '@/core/common/enums/ErrorMessages'; 4 | 5 | /** 6 | * Given breakpoints, return an array of breakpoints sorted by width. This is usually 7 | * e.g. ['xxs', 'xs', 'sm', ...] 8 | * 9 | * @param {TBreakpoints} breakpoints Key/value a pair of breakpoint names to widths. 10 | * @return {TBreakpoint[]} Sorted breakpoints. 11 | */ 12 | export const sortBreakpoints = (breakpoints: TBreakpoints): TBreakpoint[] => { 13 | const keys: string[] = Object.keys(breakpoints); 14 | if (keys.length === 0) { 15 | throw new Error(ErrorMsg.INVALID_BREAKPOINT); 16 | } 17 | return keys.sort((a, b) => { 18 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 19 | // @ts-ignore 20 | return breakpoints[a] - breakpoints[b]; 21 | }); 22 | }; 23 | 24 | const isBreakPointDefined = (breakpoints: TBreakpoints): boolean => { 25 | if ( 26 | Object.hasOwn(breakpoints, 'xxl') && 27 | Object.hasOwn(breakpoints, 'xl') && 28 | Object.hasOwn(breakpoints, 'lg') && 29 | Object.hasOwn(breakpoints, 'md') && 30 | Object.hasOwn(breakpoints, 'sm') && 31 | Object.hasOwn(breakpoints, 'xs') && 32 | Object.hasOwn(breakpoints, 'xxs') 33 | ) { 34 | return true; 35 | } 36 | return false; 37 | }; 38 | 39 | /** 40 | * Given a width, find the highest breakpoint that matches is valid for it (width > breakpoint). 41 | * 42 | * @param {TBreakpoints} breakpoints Breakpoints object (e.g. {lg: 1200, md: 960, ...}) 43 | * @param {Number} width Window width. 44 | * @return {TBreakpoint} Highest breakpoint that is less than width. 45 | * @throws {Error} Invalid width. Must be greater or equal 0 46 | */ 47 | export const getBreakpointFromWidth = (breakpoints: TBreakpoints, width: number): TBreakpoint => { 48 | if (!isBreakPointDefined(breakpoints)) { 49 | throw new Error(ErrorMsg.INVALID_BREAKPOINT); 50 | } 51 | 52 | if (width < 0) { 53 | throw new Error(ErrorMsg.INVALID_WIDTH); 54 | } 55 | 56 | const sortedBreakpoints = sortBreakpoints(breakpoints); 57 | let matchingBreakpoint = sortedBreakpoints[0]; 58 | 59 | sortedBreakpoints.forEach((breakpoint, index): void => { 60 | const breakpointName = sortedBreakpoints[index]; 61 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 62 | // @ts-ignore 63 | if (width > breakpoints[breakpointName]) { 64 | matchingBreakpoint = breakpointName; 65 | } 66 | }); 67 | 68 | return matchingBreakpoint; 69 | }; 70 | /** 71 | * Given a breakpoint, get the # of cols set for it. 72 | * 73 | * @param {TBreakpoint} breakpoint Breakpoint. 74 | * @param {IColumns} cols Map of breakpoints to cols. 75 | * @return {Number} Number of cols. 76 | * @throws {Error} Column not found 77 | */ 78 | export const getColsFromBreakpoint = (breakpoint: TBreakpoint, cols: IColumns): number => { 79 | if (!breakpoint) { 80 | throw new Error(ErrorMsg.INVALID_BREAKPOINT); 81 | } 82 | 83 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 84 | // @ts-ignore 85 | if (!cols[breakpoint]) { 86 | throw new Error(ErrorMsg.INVALID_BREAKPOINT_NOT_FOUND); 87 | } 88 | 89 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 90 | // @ts-ignore 91 | return cols[breakpoint]; 92 | }; 93 | -------------------------------------------------------------------------------- /src/core/common/helpers/gridIemTypeHelpers.ts: -------------------------------------------------------------------------------- 1 | import {ILayoutItem, TLayout} from "@/components"; 2 | import {ErrorMsg} from "@/core/common/enums/ErrorMessages"; 3 | 4 | /** 5 | * Get all static elements. 6 | * @param {Array} layout Array of layout objects. 7 | * @return {Array} Array of static layout items. 8 | * @throws {String} Empty layout not allowed. 9 | */ 10 | // eslint-disable-next-line no-undef 11 | export function getAllStaticGridItems(layout: TLayout): ILayoutItem[] { 12 | if (layout.length === 0) { 13 | throw new Error(ErrorMsg.INVALID_EMPTY_LAYOUT); 14 | } 15 | return layout.filter(l => l.isStatic); 16 | } 17 | 18 | /** 19 | * Get non all static elements. 20 | * @param {Array} layout Array of layout objects. 21 | * @return {Array} Array of static layout items. 22 | * @throws {String} Empty layout not allowed. 23 | */ 24 | // eslint-disable-next-line no-undef 25 | export function getAllNonStaticGridItems(layout: TLayout): ILayoutItem[] { 26 | if (layout.length === 0) { 27 | throw new Error(ErrorMsg.INVALID_EMPTY_LAYOUT); 28 | } 29 | return layout.filter(l => !l.isStatic); 30 | } 31 | -------------------------------------------------------------------------------- /src/core/common/interfaces/eventBus.interfaces.ts: -------------------------------------------------------------------------------- 1 | export interface IEventsData { 2 | eventType: string | symbol; 3 | h: number; 4 | i: string | number; 5 | w: number; 6 | x: number; 7 | y: number; 8 | } 9 | -------------------------------------------------------------------------------- /src/core/common/interfaces/transformStyle.interfaces.ts: -------------------------------------------------------------------------------- 1 | export interface ITransformStyle { 2 | transform: string; 3 | WebkitTransform: string; 4 | MozTransform: string; 5 | msTransform: string; 6 | OTransform: string; 7 | width: string; 8 | height: string; 9 | position: `absolute` | `relative`; 10 | } 11 | 12 | export interface ITopLeftStyle { 13 | top: string; 14 | left: string; 15 | width: string; 16 | height: string; 17 | position: `absolute`; 18 | } 19 | 20 | export interface ITopRightStyle { 21 | top: string; 22 | right: string; 23 | width: string; 24 | height: string; 25 | position: string; 26 | } 27 | -------------------------------------------------------------------------------- /src/core/common/types/TMovingDirections.ts: -------------------------------------------------------------------------------- 1 | import {EMovingDirections} from "@/core/common/enums/EMovingDirections"; 2 | 3 | export type TMovingDirection = keyof typeof EMovingDirections; 4 | -------------------------------------------------------------------------------- /src/core/griditem/enums/EGridItemEvents.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Events emitted by the GridItem component 3 | */ 4 | export enum EGridItemEvent { 5 | CONTAINER_RESIZED = `container-resized`, 6 | DRAG = `drag`, 7 | DRAGGED = `dragged`, 8 | MOVE = `item-move`, 9 | MOVED = `item-moved`, 10 | REMOVE_ITEM = `remove-grid-item`, 11 | RESIZE = `resize`, 12 | RESIZED = `resized`, 13 | } 14 | -------------------------------------------------------------------------------- /src/core/griditem/helpers/gridItemCalculateHelper.ts: -------------------------------------------------------------------------------- 1 | import { ErrorMsg } from '@/core/common/enums/ErrorMessages'; 2 | 3 | // Similar to _.clamp from lodash. 4 | export const clamp = (num: number, lowerBound: number, upperBound: number): number => { 5 | const res = Math.max(Math.min(num, upperBound), lowerBound); 6 | return res; 7 | }; 8 | 9 | /** 10 | * Calculation the GridItem's Width and height. 11 | * @param {Number} gridUnits 12 | * @param {Number} colOrRowSize 13 | * @param {Number} marginPx 14 | * @return {Number} The result of the calculation. If gridUnits is not infinite, it returns the gridUnits. 15 | * Otherwise, the result is being calculated. 16 | */ 17 | export const calcGridItemWH = (gridUnits: number, colOrRowSize: number, marginPx: number): number => { 18 | if (gridUnits <= 0) { 19 | throw new Error(ErrorMsg.INVALID_GRID_UNITS); 20 | } 21 | 22 | if (colOrRowSize <= 0) { 23 | throw new Error(ErrorMsg.INVALID_COL_OR_ROW_SIZE); 24 | } 25 | 26 | if (marginPx < 0) { 27 | throw new Error(ErrorMsg.INVALID_MARGIN); 28 | } 29 | 30 | if (!Number.isFinite(gridUnits)) { 31 | return gridUnits; 32 | } 33 | return Math.round(colOrRowSize * gridUnits + Math.max(0, gridUnits - 1) * marginPx); 34 | }; 35 | 36 | /** 37 | * Calculating the Column width. 38 | * @param {Number} containerWidth The width of the GridLayout container 39 | * @param {Number} marginLeftRight Left snd Right margin value. 40 | * @param {Number} cols Number of columns defined in the layout. 41 | * @return {Number} The new column width. 42 | */ 43 | export const calcColWidth = (containerWidth: number, marginLeftRight: number, cols: number): number => { 44 | if (containerWidth < 1) { 45 | throw new Error(ErrorMsg.INVALID_PARAM_CONTAINER_WIDTH); 46 | } 47 | 48 | if (marginLeftRight < 0) { 49 | throw new Error(ErrorMsg.INVALID_MARGIN_LEFT_RIGHT); 50 | } 51 | 52 | if (cols < 1) { 53 | throw new Error(ErrorMsg.INVALID_COLUMNS); 54 | } 55 | 56 | // if(marginLeftRight === 0){ 57 | // return (containerWidth * (cols + 1)) / cols; 58 | // } 59 | return (containerWidth - marginLeftRight * (cols + 1)) / cols; 60 | }; 61 | -------------------------------------------------------------------------------- /src/core/griditem/interfaces/grid-item.interfaces.ts: -------------------------------------------------------------------------------- 1 | export interface ICalcXy { 2 | x: number; 3 | y: number; 4 | } 5 | 6 | export interface ICalcWh { 7 | w: number; 8 | h: number; 9 | } 10 | 11 | export interface IGridItemPosition { 12 | left?: number; 13 | right?: number; 14 | top: number; 15 | width: number; 16 | height: number; 17 | } 18 | 19 | export interface IGridItemWidthHeight { 20 | width: number; 21 | height: number; 22 | } 23 | 24 | // Interfaces describing the resize interact edges. 25 | export interface IInteractEdges { 26 | bottom: boolean; 27 | left: boolean; 28 | right: boolean; 29 | top: boolean; 30 | } 31 | -------------------------------------------------------------------------------- /src/core/gridlayout/enums/EDragEvent.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Events emitted by the browser. 3 | */ 4 | export enum EDragEvent { 5 | DRAG_END = `dragend`, 6 | DRAG_MOVE= `dragmove`, 7 | DRAG_START = `dragstart`, 8 | } 9 | -------------------------------------------------------------------------------- /src/core/gridlayout/enums/EGridLayoutEvents.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Events emitted by the GridLayout component 3 | */ 4 | export enum EGridLayoutEvent { 5 | BREAKPOINT_CHANGED = `breakpoint-changed`, 6 | CHANGED_DIRECTION = `changed-direction`, 7 | COLUMNS_CHANGED = `columns-changed`, 8 | CONTAINER_RESIZED = `container-resized`, 9 | DRAG_END = `dragend`, 10 | DRAG_MOVE= `dragmove`, 11 | DRAG_START = `dragstart`, 12 | LAYOUT_BEFORE_MOUNT = `layout-before-mount`, 13 | LAYOUT_CREATED = `layout-created`, 14 | LAYOUT_MOUNTED = `layout-mounted`, 15 | LAYOUT_READY = `layout-ready`, 16 | LAYOUT_UPDATED = `layout-updated`, 17 | LAYOUT_UPDATE = `update:layout`, 18 | } 19 | -------------------------------------------------------------------------------- /src/core/gridlayout/helpers/collissionHelper.ts: -------------------------------------------------------------------------------- 1 | import { ILayoutItem, TLayout } from '@/components'; 2 | import { ErrorMsg } from '@/core/common/enums/ErrorMessages'; 3 | 4 | /** 5 | * Given two layout items, check if they collide. 6 | * 7 | * @return {Boolean} True if colliding. 8 | */ 9 | export function collides(l1: ILayoutItem, l2: ILayoutItem): boolean { 10 | if (l1 === null || l2 === null || l1 === undefined || l2 === undefined) { 11 | throw new Error(ErrorMsg.INVALID_PARAMS); 12 | } 13 | 14 | if (l1 === l2) return false; // same element 15 | if (l1.y + l1.h <= l2.y) return false; // l1 is above l2 16 | if (l1.y >= l2.y + l2.h) return false; // l1 is below l2 17 | if (l1.x + l1.w <= l2.x) return false; // l1 is left of l2 18 | if (l1.x >= l2.x + l2.w) return false; // l1 is right of l2 19 | return true; // boxes overlap 20 | } 21 | 22 | /** 23 | * Returns all the items which collides in the layout 24 | * It doesn't appear to matter which order we approach this from, although 25 | * perhaps that is the wrong thing to do. 26 | * 27 | * @param {TLayout} layout The entire grid layout. 28 | * @param {ILayoutItem} layoutItem Layout item. 29 | * @return {ILayoutItem|undefined} A colliding layout item, or undefined. 30 | * @throws {Error} Empty layout. 31 | */ 32 | export function getAllCollisions(layout: TLayout, layoutItem: ILayoutItem): ILayoutItem[] { 33 | if (layout === undefined || layout.length === 0 || layoutItem === undefined) { 34 | throw new Error(ErrorMsg.INVALID_PARAMS); 35 | } 36 | return layout.filter((l) => collides(l, layoutItem)); 37 | } 38 | 39 | /** 40 | * Returns the first item this layout collides with. 41 | * It doesn't appear to matter which order we approach this from, although 42 | * perhaps that is the wrong thing to do. 43 | * 44 | * @param {TLayout} layout The entire grid layout. 45 | * @param {ILayoutItem} layoutItem Layout item. 46 | * @return {ILayoutItem|undefined} A colliding layout item, or undefined. 47 | * @throws {Error} Empty layout. 48 | */ 49 | export function getFirstCollision(layout: TLayout, layoutItem: ILayoutItem): ILayoutItem | undefined { 50 | if (layout === undefined || layout.length === 0 || layoutItem === undefined) { 51 | return undefined; 52 | } 53 | 54 | // if layout doesnt have static item it will cause error 55 | // cannot drag or do anything 56 | 57 | for (let i = 0, len = layout.length; i < len; i++) { 58 | if (collides(layout[i], layoutItem)) { 59 | return layout[i]; 60 | } 61 | } 62 | return undefined; 63 | } 64 | -------------------------------------------------------------------------------- /src/core/gridlayout/helpers/gridLayoutHelper.ts: -------------------------------------------------------------------------------- 1 | import {TLayout} from "@/components"; 2 | import {ErrorMsg} from "@/core/common/enums/ErrorMessages"; 3 | 4 | /** 5 | * Return the bottom coordinate of the layout. 6 | * 7 | * @param {Array} layout Layout array. 8 | * @return {Number} Bottom coordinate. 9 | */ 10 | export function getBottomYCoordinate(layout: TLayout): number { 11 | if(layout === undefined || layout.length === 0){ 12 | throw new Error(ErrorMsg.INVALID_LAYOUT); 13 | } 14 | let max = 0; 15 | let bottomY; 16 | for (let i = 0, len = layout.length; i < len; i++) { 17 | bottomY = layout[i].y + layout[i].h; 18 | if (bottomY > max) max = bottomY; 19 | } 20 | return max; 21 | } 22 | -------------------------------------------------------------------------------- /src/core/gridlayout/helpers/responsiveHelper.ts: -------------------------------------------------------------------------------- 1 | import {TLayout, TResponsiveLayout} from "@/components"; 2 | import {TBreakpoint, TBreakpoints} from "@/components/Grid/layout-definition"; 3 | import {cloneLayout, compactLayout} from "@/core/helpers/utils"; 4 | import {correctBounds} from "@/core/helpers/responsiveUtils"; 5 | 6 | /** 7 | * Given existing layouts and a new breakpoint, find or generate a new layout. 8 | * 9 | * This finds the layout above the new one and generates from it, if it exists. 10 | * 11 | * @param {TLayout} orgLayout Original layout. 12 | * @param {TLayout} layouts Existing layouts. 13 | * @param {TBreakpoints} breakpoints All breakpoints. 14 | * @param {TBreakpoint} breakpoint New breakpoint. 15 | * @param {TBreakpoint} lastBreakpoint Last breakpoint (for fallback). 16 | * @param {Number} cols Column count at new breakpoint. 17 | * @param {Boolean} verticalCompact Whether or not to compact the layout vertically. 18 | * @param {Boolean} distributeEvenly 19 | * @return {TLayout} New layout. 20 | */ 21 | export const findOrGenerateResponsiveLayout = ( 22 | // TODO obsolete code.. 23 | orgLayout: TLayout, 24 | layouts: TResponsiveLayout, 25 | breakpoints: TBreakpoints, 26 | breakpoint: TBreakpoint, 27 | lastBreakpoint: TBreakpoint, 28 | cols: number, 29 | verticalCompact: boolean, 30 | distributeEvenly: boolean, 31 | ): TLayout => { 32 | // we cant return the layouts[breakpoints] directly because we don't know whether user change the layout or not 33 | 34 | // Find or generate the next layout 35 | const layout = cloneLayout(orgLayout || []); 36 | 37 | return compactLayout(correctBounds(layout, {cols}, distributeEvenly), verticalCompact); 38 | }; 39 | -------------------------------------------------------------------------------- /src/core/gridlayout/helpers/sortHelper.ts: -------------------------------------------------------------------------------- 1 | import { ILayoutItem, TLayout } from '@/components'; 2 | 3 | /** 4 | * Get layout items sorted from top left to right and down. 5 | * 6 | * @param {TLayout} layout Array of layout objects. 7 | * @return {TLayout} Sorted layout 8 | */ 9 | export function sortLayoutItemsByRowCol(layout: TLayout): TLayout { 10 | const a: ILayoutItem[] = []; 11 | return a.concat(layout).sort((itemA, itemB) => { 12 | if (itemA.y === itemB.y && itemA.x === itemB.x) { 13 | return 0; 14 | } 15 | 16 | if (itemA.y > itemB.y || (itemA.y === itemB.y && itemA.x > itemB.x)) { 17 | return 1; 18 | } 19 | 20 | return -1; 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /src/core/gridlayout/interfaces/layout-data.interface.ts: -------------------------------------------------------------------------------- 1 | import elementResizeDetectorMaker from 'element-resize-detector'; 2 | import { TLayout } from '@/components'; 3 | 4 | export interface IPlaceholder { 5 | h: number; 6 | i: number | string; 7 | x: number; 8 | y: number; 9 | w: number; 10 | } 11 | 12 | export interface ILayoutData { 13 | erd: elementResizeDetectorMaker.Erd | null; 14 | isDragging: boolean; 15 | layouts: { [key: string]: TLayout | any }; 16 | lastBreakpoint: string | null; 17 | lastLayoutLength: number; 18 | mergeStyle: { [key: string]: string }; 19 | originalLayout: TLayout | null; 20 | placeholder: IPlaceholder; 21 | positionsBeforeDrag: { [key: string]: string }; 22 | width: number | null; 23 | this$refsLayout: HTMLElement; 24 | } 25 | 26 | export interface IPositionParameters { 27 | cols: number; 28 | containerWidth: number | null; 29 | margin: [number, number]; 30 | maxRows: number | null; 31 | rowHeight: number | null; 32 | } 33 | -------------------------------------------------------------------------------- /src/core/helpers/DOM.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Checking if the window object exists. 3 | */ 4 | const hasWindow = (): boolean => { 5 | return typeof window !== `undefined`; 6 | }; 7 | 8 | /** 9 | * Adding a event listener to the window object. 10 | * @param {String} event Name of the event to listen for. 11 | * @param {Function} callback Callback function. 12 | * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener 13 | */ 14 | export const addWindowEventListener = (event: string, callback: () => any): boolean => { 15 | if(!hasWindow) { 16 | callback(); 17 | return false; 18 | } 19 | window.addEventListener(event, callback); 20 | return true; 21 | }; 22 | 23 | /** 24 | * Removing a event listener from the window object. 25 | * @param {String} event Name of the event to remove. 26 | * @param {Function} callback Callback function. 27 | * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener 28 | */ 29 | export const removeWindowEventListener = (event: string, callback: () => any): void => { 30 | if(!hasWindow) { 31 | return; 32 | } 33 | window.removeEventListener(event, callback); 34 | }; 35 | -------------------------------------------------------------------------------- /src/core/helpers/calculateUtils.ts: -------------------------------------------------------------------------------- 1 | import {ICalcXy} from '@/core/griditem/interfaces/grid-item.interfaces'; 2 | import {calcColWidth} from "@/core/griditem/helpers/gridItemCalculateHelper"; 3 | import {ErrorMsg} from "@/core/common/enums/ErrorMessages"; 4 | 5 | 6 | const validateXYParams = ( 7 | rowHeight: number, 8 | margin: [x: number, y: number], 9 | cols: number, 10 | innerH: number, 11 | innerW: number, 12 | maxRows: number, 13 | containerWidth: number): void => { 14 | 15 | if (rowHeight < 1) { 16 | throw new Error(ErrorMsg.INVALID_PARAM_ROW_HEIGHT); 17 | } 18 | 19 | if (margin[0] < 1 || margin[1] < 1) { 20 | throw new Error(ErrorMsg.INVALID_PARAM_MARGIN); 21 | } 22 | 23 | if (cols < 1) { 24 | throw new Error(ErrorMsg.INVALID_PARAM_COLS); 25 | } 26 | 27 | if (innerH < 1) { 28 | throw new Error(ErrorMsg.INVALID_PARAM_INNER_H); 29 | } 30 | 31 | if (innerW < 1) { 32 | throw new Error(ErrorMsg.INVALID_PARAM_INNER_W); 33 | } 34 | 35 | if (cols < 1) { 36 | throw new Error(ErrorMsg.INVALID_PARAM_COLS); 37 | } 38 | 39 | if (maxRows < 1) { 40 | throw new Error(ErrorMsg.INVALID_PARAM_MAX_ROWS); 41 | } 42 | 43 | if (containerWidth < 1) { 44 | throw new Error(ErrorMsg.INVALID_PARAM_CONTAINER_WIDTH); 45 | } 46 | }; 47 | /** 48 | * Translate x and y coordinates from pixels to grid units. 49 | * @param {Number} top Top position (relative to parent) in pixels. 50 | * @param {Number} left Left position (relative to parent) in pixels. 51 | * @param {[]} margin Left Right margin. 52 | * @param {Number} rowHeight Height of each row in the layout. 53 | * @param {Number} cols Number of GridItem columns specified in the GridLayout (colNum property in the GridLayout component). 54 | * @param {Number} innerH GridItem height in GridLayout units. 55 | * @param {Number} innerW GridItem width in GridLayout units. 56 | * @param {Number} maxRows Number of rows (maxRows property in GridLayout) in the GridLayout. 57 | * @param {Number} containerWidth Width of the GridLayout container. 58 | * @return {ICalcXy} x and y in grid units. 59 | */ 60 | export const calcXY = ( 61 | top: number, 62 | left: number, 63 | margin: [x: number, y: number], 64 | rowHeight: number, 65 | cols: number, 66 | innerH: number, 67 | innerW: number, 68 | maxRows: number, 69 | containerWidth: number 70 | ): ICalcXy => { 71 | 72 | validateXYParams(rowHeight, margin,cols,innerH, innerW, maxRows, containerWidth); 73 | 74 | const colWidth = calcColWidth(containerWidth, margin[0], cols); 75 | let x = Math.round((left - margin[0]) / (colWidth + margin[0])); 76 | let y = Math.round((top - margin[1]) / (rowHeight + margin[1])); 77 | 78 | // Capping 79 | x = Math.max(Math.min(x, cols - innerW), 0); 80 | y = Math.max(Math.min(y, maxRows - innerH), 0); 81 | 82 | return { 83 | x, 84 | y, 85 | }; 86 | }; 87 | -------------------------------------------------------------------------------- /src/core/helpers/draggableUtils.ts: -------------------------------------------------------------------------------- 1 | import { IPoint } from '@/core/helpers/point.interface'; 2 | 3 | /** 4 | * Checking if the number is a real number and not NaN. 5 | * @param num The number to validate. 6 | * @returns boolean If the param is a real number it returns true, if not it returns false. 7 | */ 8 | function isNum(num: number): boolean { 9 | return !Number.isNaN(num); 10 | } 11 | 12 | /** 13 | * Get {x, y} positions from event. 14 | * @param evt 15 | */ 16 | export function offsetXYFromParentOf(evt: MouseEvent): IPoint { 17 | const t = evt.target as HTMLElement; 18 | const offsetParent = t.offsetParent || document.body; 19 | const offsetParentRect = 20 | t.offsetParent === document.body 21 | ? { 22 | left: 0, 23 | top: 0, 24 | } 25 | : offsetParent.getBoundingClientRect(); 26 | 27 | const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left; 28 | const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top; 29 | 30 | /* const x = Math.round(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left); 31 | const y = Math.round(evt.clientY + offsetParent.scrollTop - offsetParentRect.top); */ 32 | 33 | return { 34 | x, 35 | y, 36 | }; 37 | } 38 | 39 | export interface IDraggableCoreData { 40 | deltaX: number; 41 | deltaY: number; 42 | lastX: number; 43 | lastY: number; 44 | x: number; 45 | y: number; 46 | } 47 | 48 | /** 49 | * Create a data object exposed by 's events 50 | * @param lastX 51 | * @param lastY 52 | * @param x 53 | * @param y 54 | */ 55 | export function createCoreData(lastX: number, lastY: number, x: number, y: number): IDraggableCoreData { 56 | // State changes are often (but not always!) async. We want the latest value. 57 | const isStart = !isNum(lastX); 58 | 59 | if (isStart) { 60 | // If this is our first move, use the x and y as last coords. 61 | return { 62 | deltaX: 0, 63 | deltaY: 0, 64 | lastX: x, 65 | lastY: y, 66 | x, 67 | y, 68 | }; 69 | } 70 | // Otherwise calculate proper values. 71 | return { 72 | deltaX: x - lastX, 73 | deltaY: y - lastY, 74 | lastX, 75 | lastY, 76 | x, 77 | y, 78 | }; 79 | } 80 | -------------------------------------------------------------------------------- /src/core/helpers/layoutUtils.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/src/core/helpers/layoutUtils.ts -------------------------------------------------------------------------------- /src/core/helpers/point.interface.ts: -------------------------------------------------------------------------------- 1 | export interface IPoint { 2 | x: number; 3 | y: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/core/helpers/responsiveUtils.ts: -------------------------------------------------------------------------------- 1 | import {TLayout} from '@/components/Grid/layout-definition'; 2 | import {getAllStaticGridItems} from "@/core/common/helpers/gridIemTypeHelpers"; 3 | import {getFirstCollision} from "@/core/gridlayout/helpers/collissionHelper"; 4 | import {moveToCorrectPlace} from "@/core/gridlayout/helpers/moveHelper"; 5 | 6 | /** 7 | * Given a layout, make sure all elements fit within its bounds. 8 | * 9 | * @param {TLayout} layout Layout array. 10 | * @param {Number} bounds Number of columns. 11 | * @param {Boolean} distributeEvenly Enforces that a grid item is moved all the way to left/right when there is available space for it 12 | * @returns {TLayout} The new adjusted layout. 13 | */ 14 | export function correctBounds(layout: TLayout, bounds: { cols: number }, distributeEvenly: boolean): TLayout { 15 | const collidesWith = getAllStaticGridItems(layout); 16 | const staticItem = getAllStaticGridItems(layout); 17 | for (let i = 0, len = staticItem.length; i < len; i++) { 18 | // move static item first 19 | // try not move their y 20 | while (staticItem[i].x + staticItem[i].w > bounds.cols || getFirstCollision(staticItem, staticItem[i])) { 21 | if(staticItem[i].x <= 0) { 22 | // Can not move the item more than to position 0 on x-axis. 23 | } 24 | // Moving to the left 25 | staticItem[i].x -= 1; 26 | } 27 | } 28 | 29 | for (let i = 0, len = layout.length; i < len; i++) { 30 | const l = layout[i]; 31 | 32 | if (distributeEvenly) { 33 | // Fix for issue: https://github.com/gwinnem/vue-responsive-grid-layout/issues/2 34 | // it's not static, and it's out of layout 35 | if (!collidesWith.includes(l) && l.x + l.w > bounds.cols) { 36 | moveToCorrectPlace(l, bounds, collidesWith); 37 | } 38 | } else if (!distributeEvenly) { 39 | // Overflows right, move item to the left 40 | if (l.x + l.w > bounds.cols) { 41 | l.x = bounds.cols - l.w; 42 | } 43 | } 44 | // Overflows left 45 | // TODO experiment to get a layout where this is the case, 01.04.2023, this is not being triggered.. 46 | if (l.x < 0) { 47 | l.x = 0; 48 | // this will cause incorrect width when drag item from outside 49 | // l.w = bounds.cols; 50 | } 51 | 52 | if (!l.isStatic) { 53 | collidesWith.push(l); 54 | } 55 | // this will cause the item which is real static be moved 56 | // else { 57 | // // If this is static and collides with other statics, we must move it down. 58 | // // We have to do something nicer than just letting them overlap. 59 | // while (getFirstCollision(collidesWith, l)) { 60 | // l.y++; 61 | // } 62 | // } 63 | } 64 | return layout; 65 | } 66 | -------------------------------------------------------------------------------- /src/core/validators/breakpoint-validator.ts: -------------------------------------------------------------------------------- 1 | import { keysValidator } from './keys-validator'; 2 | import { TBreakpoints } from '@/components/Grid/layout-definition'; 3 | 4 | export const keysValidatorPayload = { 5 | invalidKeys1: [`lg`, `md`, `sm`, `xs`, `xxs`], 6 | invalidKeys2: [`1`, `2`, `3`, `4`, `5`], 7 | validKeys: [`xxl`, `xl`, `lg`, `md`, `sm`, `xs`, `xxs`], 8 | }; 9 | 10 | export const breakpointsValidator = (cols: TBreakpoints): boolean => { 11 | const propColsKeys = (Object.keys(cols) as (keyof typeof cols)[]); 12 | const colsValues = propColsKeys.map(k => typeof cols[k] === `number`); 13 | 14 | return keysValidator(keysValidatorPayload.validKeys, propColsKeys) && colsValues.indexOf(false) === -1; 15 | }; 16 | -------------------------------------------------------------------------------- /src/core/validators/keys-validator.ts: -------------------------------------------------------------------------------- 1 | 2 | export const keysValidator = (requiredKeys: string[], propsKeys: string[]): boolean => { 3 | const coincidenceKeys = propsKeys.filter((k) => requiredKeys.indexOf(k) >= 0); 4 | 5 | return propsKeys.length >= requiredKeys.length && coincidenceKeys.length === requiredKeys.length; 6 | }; 7 | 8 | const isKeyNumericAndMinValidValue = (value: any, str: string, minValue: number): boolean => { 9 | const result = value[str]; 10 | if(typeof result !== 'number') { 11 | return false; 12 | } 13 | 14 | return (Number.isFinite(result) && result > minValue) || result === minValue; 15 | }; 16 | 17 | const isLayoutCorrectSize = (layoutItem: object): boolean => { 18 | if ( 19 | layoutItem.hasOwnProperty('i') && 20 | layoutItem.hasOwnProperty('h') && 21 | layoutItem.hasOwnProperty('w') && 22 | layoutItem.hasOwnProperty('x') && 23 | layoutItem.hasOwnProperty('y') 24 | ) 25 | return true; 26 | 27 | return false; 28 | }; 29 | 30 | const isKeyNumeric = (value: any, str: string): boolean => { 31 | return Number.isFinite(value[str]); 32 | }; 33 | 34 | const isValidIKeyString = (value: any): boolean => { 35 | const result = value['i']; 36 | return typeof result === 'string' && value['i'].length > 0; 37 | }; 38 | 39 | const isIValid = (layoutItem: object): boolean => { 40 | const tmpIsNumeric = isKeyNumeric(layoutItem, 'i'); 41 | const tmpIsString = isValidIKeyString(layoutItem); 42 | if ((!tmpIsNumeric && !tmpIsString) || (tmpIsNumeric && tmpIsString)) return false; 43 | return true; 44 | }; 45 | 46 | export const validateLayoutItemRequiredKeys = (layoutItem: Object): boolean => { 47 | if (!isLayoutCorrectSize(layoutItem)) return false; 48 | if (!isIValid(layoutItem)) return false; 49 | if (!isKeyNumericAndMinValidValue(layoutItem, 'h', 1)) return false; 50 | if (!isKeyNumericAndMinValidValue(layoutItem, 'w', 1)) return false; 51 | if (!isKeyNumericAndMinValidValue(layoutItem, 'x', 0)) return false; 52 | if (!isKeyNumericAndMinValidValue(layoutItem, 'y', 0)) return false; 53 | 54 | return true; 55 | }; 56 | -------------------------------------------------------------------------------- /src/core/validators/layout-validator.ts: -------------------------------------------------------------------------------- 1 | import { TLayout } from '@/components/Grid/layout-definition'; 2 | import { keysValidator } from './keys-validator'; 3 | import { ErrorMsg } from '@/core/common/enums/ErrorMessages'; 4 | 5 | export const layoutValidatorPayload = { 6 | invalidOptionalLayout: { 7 | h: 1, 8 | i: -1, 9 | isDraggable: true, 10 | isResizable: false, 11 | isStatic: false, 12 | maxH: 0, 13 | maxW: 0, 14 | minH: -1, 15 | minW: 0, 16 | moved: false, 17 | w: 1, 18 | x: 0, 19 | y: 0, 20 | }, 21 | invalidRequiredLayout: { 22 | h: 1, 23 | i: 1, 24 | w: 0, 25 | x: 0, 26 | y: 'a', 27 | }, 28 | invalidRequiredLayoutTwo: { 29 | h: 0, 30 | i: 1, 31 | w: 0, 32 | x: 0, 33 | }, 34 | validOptionalLayout: { 35 | h: 1, 36 | i: 0, 37 | isDraggable: true, 38 | isResizable: false, 39 | isStatic: false, 40 | maxH: 0, 41 | maxW: 0, 42 | minH: 0, 43 | minW: 0, 44 | moved: true, 45 | w: 1, 46 | x: 0, 47 | y: 0, 48 | }, 49 | validRequiredLayout: { 50 | h: 0, 51 | i: -1, 52 | w: 0, 53 | x: 0, 54 | y: 0, 55 | }, 56 | }; 57 | 58 | /** 59 | * Validates that a layout is valid. 60 | * @param layout 61 | * @returns True if layout is valid 62 | */ 63 | export const layoutValidator = (layout: TLayout): boolean => { 64 | if (layout.length === 0) { 65 | throw new Error(ErrorMsg.INVALID_LAYOUT); 66 | } 67 | 68 | const { validOptionalLayout, validRequiredLayout } = layoutValidatorPayload; 69 | const validLayout = { ...validRequiredLayout, ...validOptionalLayout }; 70 | const requiredKeys = Object.keys(validRequiredLayout); 71 | const requiredKeysValid = layout.map((l) => keysValidator(requiredKeys, Object.keys(l))); 72 | 73 | if (requiredKeysValid.includes(false)) { 74 | return false; 75 | } 76 | 77 | const validTypes = layout.map((l) => { 78 | const layoutItemKeys = Object.keys(l) as (keyof typeof l)[]; 79 | return layoutItemKeys.map((k) => (validLayout[k] ? typeof l[k] === typeof validLayout[k] : true)).includes(false); 80 | }); 81 | return !validTypes.includes(true); 82 | }; 83 | -------------------------------------------------------------------------------- /src/core/validators/margin-validator.ts: -------------------------------------------------------------------------------- 1 | export const marginValidator = (value: [number, number]): boolean => { 2 | const values = value.map(v => typeof v === `number`); 3 | const isLength = value.length === 2; 4 | 5 | return values.indexOf(false) === -1 && isLength && value[0] > 0 && value[1] > 0; 6 | }; 7 | -------------------------------------------------------------------------------- /src/hooks/useInstance.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import { ComponentInternalInstance, getCurrentInstance } from 'vue'; 3 | 4 | export default function useCurrentInstance(): any { 5 | const { appContext, proxy } = getCurrentInstance() as ComponentInternalInstance; 6 | 7 | const { globalProperties } = appContext.config; 8 | 9 | return { 10 | appContext, 11 | globalProperties, 12 | proxy, 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | -------------------------------------------------------------------------------- /src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | // Color used for the gridlines 2 | $grid-line-color: #000; 3 | 4 | // GridItem 5 | $grid-item-bg-color: #726e6e; 6 | $grid-item-border-radius: 12px; 7 | $grid-item-text-color: white; 8 | $grid-item-font-size: 1rem; 9 | $grid-item-static-bg-color: #393d42; 10 | 11 | // Color and opacity used to display the drag placeholder 12 | $grid-item-placeholder-bg-color: #8f3c3c; 13 | $grid-item-placeholder-opacity: .5; 14 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue' 3 | const component: DefineComponent<{}, {}, any> 4 | export default component 5 | } 6 | -------------------------------------------------------------------------------- /tests/breakpointValidator.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import { describe, expect, it } from 'vitest'; 4 | import { breakpointsValidator } from '@/core/validators/breakpoint-validator'; 5 | 6 | const breakpointsValidatorPayload = { 7 | invalidBreakpointsKeys1: { 8 | lg: 0, md: 0, sm: 0, xs: 0, xx: 0, 9 | }, 10 | invalidBreakpointsKeys2: { 11 | lg: 0, md: 0, sm: 0, xs: 0, 12 | }, 13 | invalidBreakpointsTypes: { 14 | lg: `0`, md: 0, sm: 0, xs: 0, xx: 0, 15 | }, 16 | validBreakpoints: { 17 | // eslint-disable-next-line sort-keys 18 | xxl: 10, xl: 10, lg: 10, md: 10, sm: 10, xs: 10, xxs: 0, 19 | }, 20 | }; 21 | 22 | describe(`breakpoint-validator`, () => { 23 | it(`When breakpoints are valid`, () => { 24 | const result = breakpointsValidator(breakpointsValidatorPayload.validBreakpoints); 25 | 26 | expect(result).toBe(true); 27 | }); 28 | 29 | it(`When breakpoints have invalid (keys) 1`, () => { 30 | const result = breakpointsValidator(breakpointsValidatorPayload.invalidBreakpointsKeys1); 31 | 32 | expect(result).toBe(false); 33 | }); 34 | 35 | it(`When breakpoints have invalid (keys) 2`, () => { 36 | const result = breakpointsValidator(breakpointsValidatorPayload.invalidBreakpointsKeys2); 37 | 38 | expect(result).toBe(false); 39 | }); 40 | 41 | it(`When breakpoints are invalid (types)`, () => { 42 | const result = breakpointsValidator(breakpointsValidatorPayload.invalidBreakpointsTypes); 43 | 44 | expect(result).toBe(false); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /tests/breakpointsHelper.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import {describe, expect, it} from 'vitest'; 4 | import {IBreakpoints, IColumns} from "@/components/Grid/grid-layout-props.interface"; 5 | import { 6 | getBreakpointFromWidth, 7 | getColsFromBreakpoint, 8 | sortBreakpoints 9 | } from "../src/core/common/helpers/breakpointsHelper"; 10 | import {ErrorMsg} from "../src/core/common/enums/ErrorMessages"; 11 | 12 | const breakpoints: IBreakpoints = { 13 | // eslint-disable-next-line vue/sort-keys 14 | xl: 1400, 15 | xxl: 1600, 16 | // eslint-disable-next-line vue/sort-keys 17 | lg: 1200, 18 | md: 996, 19 | sm: 768, 20 | xs: 480, 21 | xxs: 0, 22 | }; 23 | 24 | describe(`sortBreakpoints`, () => { 25 | it(`Breakpoints are sorted correctly`, () => { 26 | const sortedBreakPoints = sortBreakpoints(breakpoints); 27 | const resultBreakPoints = [ 28 | `xxs`, 29 | `xs`, 30 | `sm`, 31 | `md`, 32 | `lg`, 33 | `xl`, 34 | `xxl` 35 | ]; 36 | 37 | expect(sortedBreakPoints).toMatchObject(resultBreakPoints); 38 | }); 39 | 40 | it(`Breakpoints are sorted correctly 1`, () => { 41 | const breakpoints: IBreakpoints = { 42 | xxs: 0, 43 | md: 996, 44 | xs: 480, 45 | sm: 768, 46 | }; 47 | const sortedBreakPoints = sortBreakpoints(breakpoints); 48 | const resultBreakPoints = [ 49 | `xxs`, 50 | `xs`, 51 | `sm`, 52 | `md` 53 | ]; 54 | 55 | expect(sortedBreakPoints).toMatchObject(resultBreakPoints); 56 | }); 57 | 58 | it(`Empty Breakpoint array throws error`, () => { 59 | expect(() => sortBreakpoints([])).toThrowError(ErrorMsg.INVALID_BREAKPOINT); 60 | }); 61 | 62 | it(`Returned Breakpoint array has correct length`, () => { 63 | const breakpoints: IBreakpoints = { 64 | xxs: 0, 65 | md: 996, 66 | xs: 480, 67 | sm: 768, 68 | }; 69 | expect(() => sortBreakpoints(breakpoints).length === 4).toBeTruthy(); 70 | }); 71 | }); 72 | 73 | describe(`getBreakpointFromWidth`, () => { 74 | it('Should throw error when no breakpoint is passed', () => { 75 | expect(() => getBreakpointFromWidth({}, 1200)).toThrowError(ErrorMsg.INVALID_BREAKPOINT); 76 | }); 77 | 78 | it(`Correct Breakpoint is returned 1500 = xl`, () => { 79 | expect(getBreakpointFromWidth(breakpoints, 1500) === `xl`).toBeTruthy(); 80 | }); 81 | 82 | it(`Correct Breakpoint is returned 1201 = lg`, () => { 83 | expect(getBreakpointFromWidth(breakpoints, 1201) === `lg`).toBeTruthy(); 84 | }); 85 | 86 | it(`Correct Breakpoint is returned 2000`, () => { 87 | expect(getBreakpointFromWidth(breakpoints, 2000) === `xxl`).toBeTruthy(); 88 | }); 89 | 90 | it(`Invalid width should throw error`, () => { 91 | expect(() => getBreakpointFromWidth(breakpoints, -99)).toThrowError(ErrorMsg.INVALID_WIDTH); 92 | }); 93 | it(`Empty breakpoints should throw error`, () => { 94 | expect(() => getBreakpointFromWidth([], 99)).toThrowError(ErrorMsg.INVALID_BREAKPOINT); 95 | }); 96 | }); 97 | 98 | const columns: IColumns = { 99 | xxl: 16, 100 | // eslint-disable-next-line vue/sort-keys 101 | xl: 12, 102 | // eslint-disable-next-line vue/sort-keys 103 | lg: 12, 104 | md: 10, 105 | sm: 6, 106 | xs: 4, 107 | xxs: 2, 108 | }; 109 | 110 | describe(`getColsFromBreakpoint tests`, () => { 111 | it(`Should throw error when breakpoint is not found`, () => { 112 | expect(() => getColsFromBreakpoint('invalid', columns)).toThrowError(ErrorMsg.INVALID_BREAKPOINT_NOT_FOUND); 113 | }); 114 | 115 | it(`Should throw error when breakpoint is empty`, () => { 116 | expect(() => getColsFromBreakpoint(``, columns)).toThrowError(ErrorMsg.INVALID_BREAKPOINT); 117 | }); 118 | 119 | it(`Should return 'columns.sm' for breakpoint sm`, () => { 120 | const colNum = getColsFromBreakpoint('sm', columns); 121 | expect(colNum).toBe(columns.sm); 122 | }); 123 | }); 124 | -------------------------------------------------------------------------------- /tests/calculateUtils.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import {describe, expect, it} from 'vitest'; 4 | import {calcXY} from "../src/core/helpers/calculateUtils"; 5 | import {ErrorMsg} from "../src/core/common/enums/ErrorMessages"; 6 | 7 | describe(`calcXY`, () => { 8 | it(`Should throw error when invalid rowHeight is passed`, () => { 9 | expect(() => calcXY(10, 589, [10, 10], 0, 6, 10, 10, 1, 1)) 10 | .toThrowError(ErrorMsg.INVALID_PARAM_ROW_HEIGHT); 11 | }); 12 | 13 | it(`Should throw error when invalid margin[0] is passed`, () => { 14 | expect(() => calcXY(10, 589, [0, 10], 60, 6, 10, 10, 1, 1)) 15 | .toThrowError(ErrorMsg.INVALID_PARAM_MARGIN); 16 | }); 17 | 18 | it(`Should throw error when invalid margin[1] is passed`, () => { 19 | expect(() => calcXY(10, 589, [10, 0], 60, 6, 10, 10, 1, 1)) 20 | .toThrowError(ErrorMsg.INVALID_PARAM_MARGIN); 21 | }); 22 | 23 | it(`Should throw error when invalid margin is passed`, () => { 24 | expect(() => calcXY(10, 589, [0, 0], 60, 6, 10, 10, 1, 1)) 25 | .toThrowError(ErrorMsg.INVALID_PARAM_MARGIN); 26 | }); 27 | 28 | it(`Should throw error when invalid innerH is passed`, () => { 29 | expect(() => calcXY(10, 589, [10, 10], 10, 10, 0, 10, 1, 1)) 30 | .toThrowError(ErrorMsg.INVALID_PARAM_INNER_H); 31 | }); 32 | 33 | it(`Should throw error when invalid innerW is passed`, () => { 34 | expect(() => calcXY(10, 589, [10, 10], 10, 10, 10, 0, 1, 1)) 35 | .toThrowError(ErrorMsg.INVALID_PARAM_INNER_W); 36 | }); 37 | 38 | it(`Should throw error when invalid cols is passed`, () => { 39 | expect(() => calcXY(10, 589, [10, 10], 10, 0, 10, 10, 1, 1)) 40 | .toThrowError(ErrorMsg.INVALID_PARAM_COLS); 41 | }); 42 | 43 | it(`Should throw error when invalid maxRows is passed`, () => { 44 | expect(() => calcXY(10, 589, [10, 10], 10, 10, 10, 10, 0, 1)) 45 | .toThrowError(ErrorMsg.INVALID_PARAM_MAX_ROWS); 46 | }); 47 | 48 | it(`Should throw error when invalid containerWidth is passed`, () => { 49 | expect(() => calcXY(10, 589, [10, 10], 10, 10, 10, 10, 1, 0)) 50 | .toThrowError(ErrorMsg.INVALID_PARAM_CONTAINER_WIDTH); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /tests/collissionHelper.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import { describe, expect, it } from 'vitest'; 4 | import { collides, getAllCollisions, getFirstCollision } from "@/core/gridlayout/helpers/collissionHelper"; 5 | import { ILayoutItem } from "@/components/Grid/layout-definition"; 6 | import { ErrorMsg } from "../src/core/common/enums/ErrorMessages"; 7 | 8 | const l1: ILayoutItem = { 9 | i: 0, 10 | h: 1, 11 | w: 1, 12 | x: 0, 13 | y: 0, 14 | } 15 | 16 | const l2: ILayoutItem = { 17 | i: 1, 18 | h: 1, 19 | w: 1, 20 | x: 0, 21 | y: 0, 22 | } 23 | 24 | const l3: ILayoutItem = { 25 | i: 1, 26 | h: 1, 27 | w: 1, 28 | x: 1, 29 | y: 0, 30 | } 31 | 32 | const l4: ILayoutItem = { 33 | i: 1, 34 | h: 1, 35 | w: 1, 36 | x: 1, 37 | y: 2, 38 | } 39 | 40 | const l5: ILayoutItem = { 41 | i: 1, 42 | h: 2, 43 | w: 2, 44 | x: 1, 45 | y: 2, 46 | } 47 | 48 | describe(`collides`, () => { 49 | 50 | it(`Should throw an error when passed empty values`, () => { 51 | expect(() => collides()).toThrowError(ErrorMsg.INVALID_PARAMS); 52 | }); 53 | 54 | 55 | it(`Should throw an error when first layout item is undefined`, () => { 56 | expect(() => collides(undefined, l2)).toThrowError(ErrorMsg.INVALID_PARAMS); 57 | }); 58 | 59 | it(`Should throw an error when second layout item is undefined`, () => { 60 | expect(() => collides(l1, undefined)).toThrowError(ErrorMsg.INVALID_PARAMS); 61 | }); 62 | 63 | it(`Should throw an error when first layout item is null`, () => { 64 | expect(() => collides(null, l2)).toThrowError(ErrorMsg.INVALID_PARAMS); 65 | }); 66 | 67 | it(`Should throw an error when second layout item is null`, () => { 68 | expect(() => collides(l1, null)).toThrowError(ErrorMsg.INVALID_PARAMS); 69 | }); 70 | 71 | it(`Should return false when the same GridItem is passed as parameters`, () => { 72 | const result = collides(l1, l1); 73 | expect(result).toBe(false); 74 | }); 75 | 76 | if('Should return false when l1 is left of l2', () => { 77 | const result = collides(l1, l3); 78 | expect(result).toBe(false); 79 | }); 80 | 81 | it(`Should return false when l1 is right of l2`, () => { 82 | const result = collides(l3, l1); 83 | expect(result).toBe(false); 84 | }); 85 | 86 | it(`Should return false when l1 is above l2`, () => { 87 | // l1.y + l1.h <= l2.y 88 | const la: ILayoutItem = { 89 | i: 1, 90 | h: 1, 91 | w: 1, 92 | x: 1, 93 | y: 0, 94 | } 95 | 96 | const lb: ILayoutItem = { 97 | i: 1, 98 | h: 1, 99 | w: 1, 100 | x: 0, 101 | y: 3, 102 | } 103 | const result = collides(lb, la); 104 | expect(result).toBe(false); 105 | }); 106 | 107 | it(`Should return false when l1 is below l2`, () => { 108 | const result = collides(l2, l4); 109 | expect(result).toBe(false); 110 | }); 111 | 112 | it(`Should return true when items overlap`, () => { 113 | const result = collides(l5, l4); 114 | expect(result).toBe(true); 115 | }); 116 | }); 117 | 118 | describe(`getFirstCollision`, () => { 119 | it(`Should return undefined when all params are undefined`, () => { 120 | const result = getFirstCollision(); 121 | expect(result).toBe(undefined); 122 | }); 123 | 124 | it(`Should return l1 since this collides with l2`, () => { 125 | const result = getFirstCollision([ 126 | l1, 127 | l2, 128 | l3 129 | ], l2); 130 | 131 | expect(result).toMatchObject(l1); 132 | }); 133 | 134 | it(`Should return undefined when no collisions are found`, () => { 135 | const result = getFirstCollision(l1, l3); 136 | expect(result).toBe(undefined); 137 | }); 138 | }); 139 | 140 | describe(`getAllCollisions`, () => { 141 | it(`Should throw an error if params are undefined`, () => { 142 | expect(() => getAllCollisions()).toThrowError('Invalid parameter values'); 143 | }); 144 | 145 | it(`Should throw an error if layout is an empty array`, () => { 146 | expect(() => getAllCollisions([], l1)).toThrowError('Invalid parameter values'); 147 | }); 148 | 149 | it(`Should throw an error if layoutItem is undefined`, () => { 150 | expect(() => getAllCollisions([l1],)).toThrowError('Invalid parameter values'); 151 | }); 152 | 153 | it(`Should return length = 0 when no collisions are found`, () => { 154 | const result = getAllCollisions([l1], l3); 155 | expect(result.length).toBe(0); 156 | }); 157 | 158 | it(`Should return a item when collisions are found`, () => { 159 | const result = getAllCollisions([l1, l3], l2); 160 | expect(result.length).toBe(1); 161 | }); 162 | }); 163 | -------------------------------------------------------------------------------- /tests/gridItemCalculateHelper.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import { describe, expect, it } from 'vitest'; 4 | import { calcColWidth, calcGridItemWH, clamp } from '../src/core/griditem/helpers/gridItemCalculateHelper'; 5 | import { ErrorMsg } from '../src/core/common/enums/ErrorMessages'; 6 | 7 | // TODO tests should fail but not doing it. 8 | describe(`clamp`, () => { 9 | it(`Should return correct value`, () => { 10 | expect(() => clamp(10, 0, 300).toBe(10)); 11 | }); 12 | 13 | it(`Should return correct value 1`, () => { 14 | expect(() => clamp(10, 11, 300).toBe(11)); 15 | }); 16 | 17 | it(`Should return correct value 2`, () => { 18 | expect(() => clamp(1000, 11, 300).toBe(300)); 19 | }); 20 | 21 | }); 22 | 23 | describe(`calcGridItemWH tests`, () => { 24 | it(`Should allow gridUnits to be NaN`, () => { 25 | const gridUnits = NaN; 26 | const calculatedValue = calcGridItemWH(gridUnits, 1, 1); 27 | expect(calculatedValue).toBe(gridUnits); 28 | }); 29 | 30 | it(`Should throw an error if gridUnits is Null`, () => { 31 | expect(() => calcGridItemWH(null, 1, 1)).toThrowError(new Error(ErrorMsg.INVALID_GRID_UNITS)); 32 | }); 33 | 34 | it(`Should throw an error if gridUnits is 0 or negative`, () => { 35 | expect(() => calcGridItemWH(0, 1, 1)).toThrowError(new Error(ErrorMsg.INVALID_GRID_UNITS)); 36 | }); 37 | 38 | it(`Should return correct value`, () => { 39 | expect(() => { 40 | calcGridItemWH(10, 1, 1).toBe(19); 41 | }); 42 | }); 43 | 44 | it(`Should throw an error when colOrRowSize is 0 or negative`, () => { 45 | expect(() => calcGridItemWH(1, 0, 1)).toThrowError(new Error(ErrorMsg.INVALID_COL_OR_ROW_SIZE)); 46 | }); 47 | 48 | it(`Should throw an error when marginPx is negative`, () => { 49 | expect(() => calcGridItemWH(1, 1, -1)).toThrowError(new Error(ErrorMsg.INVALID_MARGIN)); 50 | }); 51 | }); 52 | 53 | describe(`calcColWidth`, () => { 54 | it(`Should throw an error when containerWidth is less than 1`, () => { 55 | expect(() => calcColWidth(0, 1, 1)).toThrowError(new Error(ErrorMsg.INVALID_PARAM_CONTAINER_WIDTH)); 56 | }); 57 | 58 | it(`Should throw an error when marginLeftRight is less than 0`, () => { 59 | expect(() => calcColWidth(1, -1, 1)).toThrowError(new Error(ErrorMsg.INVALID_MARGIN_LEFT_RIGHT)); 60 | }); 61 | 62 | it(`Should throw an error when cols is less than 1`, () => { 63 | expect(() => calcColWidth(1, 0, 0)).toThrowError(new Error(ErrorMsg.INVALID_COLUMNS)); 64 | }); 65 | 66 | it(`Should return correct value when Parameters are valid`, () => { 67 | console.log(calcColWidth(100, 10, 10)); 68 | expect(() => { 69 | calcColWidth(100, 10, 10).toBe(-1); 70 | }); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /tests/gridItemTypeHelpers.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import {describe, expect, it} from 'vitest'; 4 | import {TLayout} from "../src/components"; 5 | import {getAllNonStaticGridItems, getAllStaticGridItems} from "../src/core/common/helpers/gridIemTypeHelpers"; 6 | import {ErrorMsg} from "../src/core/common/enums/ErrorMessages"; 7 | 8 | const testLayout: TLayout = [ 9 | { 10 | i: 0, 11 | h: 1, 12 | w: 1, 13 | x: 0, 14 | y: 0, 15 | isStatic: true, 16 | }, 17 | { 18 | i: 0, 19 | h: 1, 20 | w: 1, 21 | x: 0, 22 | y: 0, 23 | isStatic: false, 24 | } 25 | ]; 26 | 27 | const testLayoutTwo: TLayout = [ 28 | { 29 | i: 0, 30 | h: 1, 31 | w: 1, 32 | x: 0, 33 | y: 0, 34 | isStatic: false, 35 | }, 36 | { 37 | i: 0, 38 | h: 1, 39 | w: 1, 40 | x: 0, 41 | y: 0, 42 | isStatic: false, 43 | }, 44 | ]; 45 | 46 | const testLayoutThree: TLayout = [ 47 | { 48 | i: 0, 49 | h: 1, 50 | w: 1, 51 | x: 0, 52 | y: 0, 53 | isStatic: true, 54 | } 55 | ]; 56 | 57 | describe(`getAllStaticGridItems`, () => { 58 | it(`It should throw error when empty layout is passed`, () => { 59 | expect(() => getAllStaticGridItems([])).toThrowError(ErrorMsg.INVALID_EMPTY_LAYOUT); 60 | }); 61 | 62 | it(`Should return one item from testLayout`, () => { 63 | const result = getAllStaticGridItems(testLayout); 64 | expect(result.length).toBe(1); 65 | }); 66 | 67 | it(`Should return empty array when no statics are found`, () => { 68 | const result = getAllStaticGridItems(testLayoutTwo); 69 | expect(result.length).toBe(0); 70 | }); 71 | }); 72 | 73 | describe(`getAllNonStaticGridItems`, () => { 74 | it(`It should throw error when empty layout is passed`, () => { 75 | expect(() => getAllNonStaticGridItems([])).toThrowError(ErrorMsg.INVALID_EMPTY_LAYOUT); 76 | }); 77 | 78 | it(`Should return one item from testLayout`, () => { 79 | const result = getAllNonStaticGridItems(testLayout); 80 | expect(result.length).toBe(1); 81 | }); 82 | 83 | it(`Should return empty array when no statics are found`, () => { 84 | const result = getAllNonStaticGridItems(testLayoutThree); 85 | expect(result.length).toBe(0); 86 | }); 87 | }); 88 | -------------------------------------------------------------------------------- /tests/gridLayoutHelper.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import {describe, expect, it} from 'vitest'; 4 | import {getBottomYCoordinate} from "../src/core/gridlayout/helpers/gridLayoutHelper"; 5 | import {TLayout} from "../src/components"; 6 | import {ErrorMsg} from "../src/core/common/enums/ErrorMessages"; 7 | 8 | const l1: TLayout = [ 9 | { 10 | i: 0, 11 | h: 1, 12 | w: 1, 13 | x: 0, 14 | y: 0, 15 | }, 16 | { 17 | i: 0, 18 | h: 1, 19 | w: 1, 20 | x: 0, 21 | y: 1, 22 | } 23 | ]; 24 | 25 | describe(`getBottomYCoordinate`, () => { 26 | it(`Should throw error when layout is undefined`, () => { 27 | expect(() => getBottomYCoordinate()).toThrowError(ErrorMsg.INVALID_LAYOUT); 28 | }); 29 | 30 | it(`Should throw error when layout is empty`, () => { 31 | expect(() => getBottomYCoordinate([])).toThrowError(ErrorMsg.INVALID_LAYOUT); 32 | }); 33 | 34 | it(`Should return 2 for the l1 layout`, () => { 35 | const result = getBottomYCoordinate(l1); 36 | expect(result).toBe(2); 37 | }); 38 | }) 39 | -------------------------------------------------------------------------------- /tests/keyValidator.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { validateLayoutItemRequiredKeys } from '../src/core/validators/keys-validator'; 3 | 4 | describe('validateLayoutItemRequiredKeys', () => { 5 | it('Should return true when all required keys are passed, and the values are valid', () => { 6 | const keys = { 7 | i: 5, 8 | x: 1, 9 | y: 1, 10 | h: 1, 11 | w: 1, 12 | }; 13 | const result = validateLayoutItemRequiredKeys(keys); 14 | return expect(result).toBe(true); 15 | }); 16 | 17 | it('Should return false when not all required keys are passed, and the values are valid', () => { 18 | const keys = { 19 | i: 5, 20 | x: 1, 21 | h: 1, 22 | w: 1, 23 | }; 24 | const result = validateLayoutItemRequiredKeys(keys); 25 | return expect(result).toBe(false); 26 | }); 27 | 28 | it('Should return false if i is not valid', () => { 29 | const keys = { 30 | i: true, 31 | x: 1, 32 | y: 1, 33 | h: 1, 34 | w: 1, 35 | }; 36 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 37 | }); 38 | 39 | it('Should return false if x is less then min value', () => { 40 | const keys = { 41 | i: 1, 42 | x: -1, 43 | y: 1, 44 | h: 1, 45 | w: 1, 46 | }; 47 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 48 | }); 49 | 50 | it('Should return false if x is not a number', () => { 51 | const keys = { 52 | i: 1, 53 | x: '', 54 | y: 1, 55 | h: 1, 56 | w: 1, 57 | }; 58 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 59 | }); 60 | 61 | it('Should return false if y is less then min value', () => { 62 | const keys = { 63 | i: 1, 64 | x: 1, 65 | y: -1, 66 | h: 1, 67 | w: 1, 68 | }; 69 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 70 | }); 71 | 72 | it('Should return false if y is not a number', () => { 73 | const keys = { 74 | i: 1, 75 | x: 1, 76 | y: '', 77 | h: 1, 78 | w: 1, 79 | }; 80 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 81 | }); 82 | 83 | it('Should return false if h is less then min value', () => { 84 | const keys = { 85 | i: 1, 86 | x: 1, 87 | y: 1, 88 | h: 0, 89 | w: 1, 90 | }; 91 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 92 | }); 93 | 94 | it('Should return false if h is not a number', () => { 95 | const keys = { 96 | i: 1, 97 | x: 1, 98 | y: 1, 99 | h: '', 100 | w: 1, 101 | }; 102 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 103 | }); 104 | 105 | it('Should return false if w is less then min value', () => { 106 | const keys = { 107 | i: 1, 108 | x: 1, 109 | y: 1, 110 | h: 1, 111 | w: 0, 112 | }; 113 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 114 | }); 115 | 116 | it('Should return false if w is not a number', () => { 117 | const keys = { 118 | i: 1, 119 | x: 1, 120 | y: 1, 121 | h: 1, 122 | w: '', 123 | }; 124 | expect(validateLayoutItemRequiredKeys(keys)).toBe(false); 125 | }); 126 | }); 127 | -------------------------------------------------------------------------------- /tests/layoutValidator.spec.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import { describe, expect, it } from 'vitest'; 3 | import { layoutValidator, layoutValidatorPayload } from '../src/core/validators/layout-validator'; 4 | import { ErrorMsg } from '../src/core/common/enums/ErrorMessages'; 5 | 6 | describe(`layoutValidator`, () => { 7 | const { 8 | invalidOptionalLayout, 9 | invalidRequiredLayout, 10 | invalidRequiredLayoutTwo, 11 | validRequiredLayout, 12 | validOptionalLayout, 13 | } = layoutValidatorPayload; 14 | 15 | it(`Should throw error when layout is undefined`, () => { 16 | expect(() => layoutValidator([])).toThrow(ErrorMsg.INVALID_LAYOUT); 17 | }); 18 | 19 | it(`Should return true When layout with required keys is valid`, () => { 20 | const data = Array.from({ length: 5 }, () => validRequiredLayout); 21 | const result = layoutValidator(data); 22 | 23 | expect(result).toBe(true); 24 | }); 25 | 26 | // TODO Fix this test it should be working 27 | // it(`Should return false When layout with required keys is invalid`, () => { 28 | // const data = Array.from({ length: 5 }, () => invalidRequiredLayout); 29 | // const result = layoutValidator(data); 30 | 31 | // expect(result).toBe(false); 32 | // }); 33 | 34 | it(`Should return false When layout with required keys is invalid`, () => { 35 | const data = Array.from({ length: 5 }, () => invalidRequiredLayoutTwo); 36 | const result = layoutValidator(data); 37 | 38 | expect(result).toBe(false); 39 | }); 40 | 41 | it(`When layout with required and optional keys is valid`, () => { 42 | const result = layoutValidator([validRequiredLayout, validOptionalLayout]); 43 | 44 | expect(result).toBe(true); 45 | }); 46 | 47 | it(`When layout with required keys is valid and optional keys is invalid`, () => { 48 | const result = layoutValidator([validRequiredLayout, invalidOptionalLayout]); 49 | 50 | expect(result).toBe(true); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /tests/marginValidator.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import { describe, expect, it } from 'vitest'; 4 | import { marginValidator } from '@/core/validators/margin-validator'; 5 | 6 | export const marginValidatorPayload = { 7 | invalidMargin1: [0, 0, 0], 8 | invalidMargin2: [`0`, 0], 9 | invalidMargin3: [0, 0], 10 | validMargin: [1, 1], 11 | }; 12 | 13 | describe(`marginValidator`, () => { 14 | 15 | it(`When margin are valid`, () => { 16 | expect(marginValidator(marginValidatorPayload.validMargin)).toBe(true); 17 | }); 18 | 19 | it(`When margin are invalid 1`, () => { 20 | expect(marginValidator(marginValidatorPayload.invalidMargin1)).toBe(false); 21 | }); 22 | 23 | it(`When margin are invalid 2`, () => { 24 | expect(marginValidator(marginValidatorPayload.invalidMargin2)).toBe(false); 25 | }); 26 | 27 | it(`When margin are invalid 3`, () => { 28 | expect(marginValidator(marginValidatorPayload.invalidMargin3)).toBe(false); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /tests/moveHelper.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { moveElement, moveToCorrectPlace } from "../src/core/gridlayout/helpers/moveHelper"; 3 | import { ErrorMsg } from "../src/core/common/enums/ErrorMessages"; 4 | import { TLayout } from "../src/components"; 5 | 6 | const testDataOne: TLayout = [ 7 | { 8 | i: 1, 9 | h: 2, 10 | w: 1, 11 | x: 0, 12 | y: 0, 13 | }, 14 | { 15 | i: 2, 16 | h: 2, 17 | w: 1, 18 | x: 1, 19 | y: 0, 20 | }, 21 | { 22 | i: 3, 23 | h: 2, 24 | w: 1, 25 | x: 2, 26 | y: 0, 27 | isStatic: true, 28 | }, 29 | { 30 | i: 4, 31 | h: 2, 32 | w: 1, 33 | x: 3, 34 | y: 0, 35 | }, 36 | { 37 | i: 5, 38 | h: 2, 39 | w: 1, 40 | x: 4, 41 | y: 0, 42 | }, 43 | { 44 | i: 6, 45 | h: 2, 46 | w: 1, 47 | x: 5, 48 | y: 0, 49 | } 50 | ]; 51 | 52 | describe(`moveToCorrectPlace`, () => { 53 | it(`Should throw an error if parameter layoutItem is undefined`, () => { 54 | expect(() => moveToCorrectPlace(null, {cols: 3}, [testDataOne[0]])) 55 | .toThrow(ErrorMsg.INVALID_LAYOUT_ITEM); 56 | }); 57 | 58 | it(`Should throw an error if parameter bounds is less than 1`, () => { 59 | expect(() => moveToCorrectPlace(testDataOne[0], { cols: 0 }, [testDataOne[0]])) 60 | .toThrow(ErrorMsg.INVALID_BOUNDS); 61 | }); 62 | }); 63 | 64 | 65 | describe(`moveElement`, () => { 66 | 67 | it(`Should throw an error if parameter x is less than 0`, () => { 68 | expect(() => moveElement(testDataOne, testDataOne[0], -1, 0, true, true, true)) 69 | .toThrowError(ErrorMsg.INVALID_PARAMS); 70 | }); 71 | 72 | it(`Should throw an error if parameter y is less than 0`, () => { 73 | expect(() => moveElement(testDataOne, testDataOne[0], 1, -1, true, true, true)) 74 | .toThrowError(ErrorMsg.INVALID_PARAMS); 75 | }); 76 | 77 | it('Should return the passed in layout when item isStatic', () => { 78 | const result = moveElement(testDataOne, { 79 | isStatic: true, 80 | i: 1, 81 | x: 1, 82 | y: 1, 83 | w: 1, 84 | h: 1 85 | }, 0, 0, false, false, false); 86 | 87 | expect(testDataOne).toMatchObject(result); 88 | }); 89 | 90 | it('Should return', () => { 91 | const result = moveElement(testDataOne, { 92 | isStatic: false, 93 | i: 1, 94 | x: 0, 95 | y: 1, 96 | w: 1, 97 | h: 1 98 | }, 0, 0, false, true, false); 99 | 100 | expect(testDataOne).toMatchObject(result); 101 | }); 102 | }); 103 | -------------------------------------------------------------------------------- /tests/sortHelper.spec.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 2 | // @ts-nocheck 3 | import { describe, expect, it } from 'vitest'; 4 | import { sortLayoutItemsByRowCol } from '../src/core/gridlayout/helpers/sortHelper'; 5 | import { TLayout } from '../src/components'; 6 | 7 | describe('sortLayoutItemsByRowCol', () => { 8 | it('Should return correct sorted layout', () => { 9 | const unsortedLayout: TLayout = [ 10 | { h: 1, i: 5, w: 2, x: 4, y: 0 }, 11 | { h: 4, i: 6, w: 4, x: 0, y: 1 }, 12 | { h: 2, i: 7, w: 2, x: 4, y: 1 }, 13 | { h: 1, i: 1, w: 1, x: 0, y: 0 }, 14 | { h: 1, i: 4, w: 1, x: 3, y: 0 }, 15 | { h: 1, i: 2, w: 1, x: 1, y: 0 }, 16 | { h: 1, i: 3, w: 1, x: 2, y: 0 }, 17 | { h: 2, i: 8, w: 2, x: 4, y: 3 }, 18 | ]; 19 | 20 | const sortedLayout: TLayout = [ 21 | { h: 1, i: 1, w: 1, x: 0, y: 0 }, 22 | { h: 1, i: 2, w: 1, x: 1, y: 0 }, 23 | { h: 1, i: 3, w: 1, x: 2, y: 0 }, 24 | { h: 1, i: 4, w: 1, x: 3, y: 0 }, 25 | { h: 1, i: 5, w: 2, x: 4, y: 0 }, 26 | { h: 4, i: 6, w: 4, x: 0, y: 1 }, 27 | { h: 2, i: 7, w: 2, x: 4, y: 1 }, 28 | { h: 2, i: 8, w: 2, x: 4, y: 3 }, 29 | ]; 30 | 31 | const result = sortLayoutItemsByRowCol(unsortedLayout); 32 | expect(result).toStrictEqual(sortedLayout); 33 | }); 34 | 35 | it('Should return correct sorted layout when layout items are colliding', () => { 36 | const unsortedLayout: TLayout = [ 37 | { h: 1, i: 1, w: 1, x: 0, y: 0 }, 38 | { h: 1, i: 2, w: 1, x: 1, y: 0 }, 39 | { h: 1, i: 4, w: 1, x: 0, y: 0 }, 40 | ]; 41 | 42 | const sortedLayout: TLayout = [ 43 | { h: 1, i: 1, w: 1, x: 0, y: 0 }, 44 | { h: 1, i: 4, w: 1, x: 0, y: 0 }, 45 | { h: 1, i: 2, w: 1, x: 1, y: 0 }, 46 | ]; 47 | 48 | const result = sortLayoutItemsByRowCol(unsortedLayout); 49 | expect(result).toStrictEqual(sortedLayout); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /tests/testLayout.ts: -------------------------------------------------------------------------------- 1 | import { TLayout } from '../src/components'; 2 | 3 | export const testLayoutOne: TLayout = [ 4 | // test 1 5 | { 6 | i: 1, 7 | h: 2, 8 | w: 1, 9 | x: 0, 10 | y: 0, 11 | isDraggable: false, 12 | isResizable: false, 13 | }, 14 | { 15 | i: 2, 16 | h: 1, 17 | w: 2, 18 | x: 1, 19 | y: 0, 20 | }, 21 | { 22 | i: 3, 23 | h: 2, 24 | w: 1, 25 | x: 2, 26 | y: 1, 27 | }, 28 | { 29 | i: 4, 30 | h: 2, 31 | w: 1, 32 | x: 3, 33 | y: 1, 34 | isStatic: true, 35 | }, 36 | { 37 | i: 5, 38 | h: 2, 39 | w: 1, 40 | x: 4, 41 | y: 0, 42 | }, 43 | { 44 | i: 6, 45 | h: 1, 46 | w: 1, 47 | x: 5, 48 | y: 0, 49 | isStatic: true, 50 | }, 51 | { 52 | i: 7, 53 | h: 3, 54 | w: 1, 55 | x: 0, 56 | y: 2, 57 | isDraggable: false, 58 | isResizable: false, 59 | }, 60 | { 61 | i: 8, 62 | h: 1, 63 | w: 1, 64 | x: 1, 65 | y: 1, 66 | isStatic: true, 67 | }, 68 | ]; 69 | 70 | export const testLayoutTwo: TLayout = [ 71 | { h: 1, i: "qwerty", w: 1, x: 0, y: 0 }, 72 | { h: 1, i: "abc", w: 1, x: 1, y: 0 }, 73 | ]; 74 | 75 | // test 3 76 | // { x:0, y:0, w:2, h:2, i:0, isDraggable: false }, 77 | // { x:2, y:0, w:2, h:2, i:1, isStatic: true }, 78 | // { x:4, y:0, w:2, h:2, i:2, isResizable: false }, 79 | // { x:0, y:2, w:2, h:2, i:3 }, 80 | // { x:2, y:2, w:2, h:2, i:4 }, 81 | // { x:4, y:2, w:2, h:2, i:5 }, 82 | // { x:0, y:4, w:2, h:2, i:6 }, 83 | // { x:2, y:4, w:2, h:2, i:7 }, 84 | // { x:4, y:4, w:2, h:2, i:8 }, 85 | // { x:0, y:6, w:2, h:2, i:9 }, 86 | // { x:2, y:6, w:2, h:2, i:10 }, 87 | // { x:4, y:6, w:2, h:2, i:11 }, 88 | 89 | // test 4 90 | // { h: 1, i: 1, w: 1, x: 0, y: 0 }, 91 | // { h: 1, i: 2, w: 1, x: 1, y: 0 }, 92 | // { h: 1, i: 3, w: 1, x: 2, y: 0 }, 93 | // { h: 1, i: 4, w: 1, x: 3, y: 0 }, 94 | // { h: 1, i: 5, w: 2, x: 4, y: 0 }, 95 | // { h: 4, i: 6, w: 4, x: 0, y: 1 }, 96 | // { h: 2, i: 7, w: 2, x: 4, y: 1 }, 97 | // { h: 2, i: 8, w: 2, x: 4, y: 3 }, 98 | -------------------------------------------------------------------------------- /tsconfig.build-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "exclude": [ 4 | "src/**/__tests__/*", 5 | "src/**/*.cy.ts", 6 | "**/*.spec.ts", 7 | "vitepress-docs/*", 8 | "tests/*", 9 | "sandbox/", 10 | "/dist", 11 | "node_modules/*", 12 | "*.tgz" 13 | ], 14 | "paths": { 15 | "@/*": [ 16 | "src/*", 17 | ], 18 | "@theme/*": ["vitepress-docs/.vitepress/theme/*"], 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tsconfig.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.node.json", 3 | "include": ["vite.config.*", "vitest.config.*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "types": [ 7 | "node", 8 | "vue", 9 | "vite/client" 10 | ], 11 | "isolatedModules": true, 12 | "skipLibCheck": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true, 5 | "declaration": true, 6 | "declarationDir": "dist/types", 7 | "esModuleInterop": true, 8 | "experimentalDecorators": true, 9 | "importHelpers": true, 10 | "isolatedModules": false, 11 | "jsx": "preserve", 12 | "lib": [ 13 | "es2022", 14 | "dom", 15 | "dom.iterable", 16 | "scripthost", 17 | "es2016.Array.Include" 18 | ], 19 | "module": "es6", 20 | "moduleResolution": "node", 21 | "newLine": "lf", 22 | // "noEmit": true, 23 | "noUnusedLocals": true, 24 | "noUnusedParameters": false, 25 | "baseUrl": ".", 26 | "paths": { 27 | "@/*": ["src/*"], 28 | "@theme/*": ["vitepress-docs/.vitepress/theme/*"], 29 | }, 30 | "resolveJsonModule": true, 31 | "skipLibCheck": true, 32 | "sourceMap": true, 33 | "strict": true, 34 | "target": "ESNext", 35 | "types": [ 36 | "node", 37 | "vue", 38 | "vite/client", 39 | "vitest/globals" 40 | ] 41 | }, 42 | "exclude": [ 43 | "src/**/__tests__/*", 44 | "src/**/*.cy.ts", 45 | "**/*.spec.ts", 46 | "/dist", 47 | "node_modules", 48 | "*.tgz", 49 | "vitepress-docs/*", 50 | "tests/*", 51 | "sandbox/*" 52 | ], 53 | "include": ["src/**/*.ts", "src/**/*.vue", "./**/*.vue"], 54 | "references": [], 55 | } 56 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import * as path from 'path'; 3 | import vue from '@vitejs/plugin-vue'; 4 | 5 | export default defineConfig({ 6 | build: { 7 | emptyOutDir: true, 8 | lib: { 9 | entry: path.resolve(__dirname, `src/components/index.ts`), 10 | fileName: format => `vue-ts-responsive-grid-layout.${format}.js`, 11 | formats: [ 12 | `es`, 13 | `umd`, 14 | ], 15 | name: `vue-ts-responsive-grid-layout`, 16 | }, 17 | outDir: `./dist`, 18 | rollupOptions: { 19 | external: [`vue`], 20 | output: { 21 | globals: { 22 | vue: `Vue`, 23 | }, 24 | }, 25 | }, 26 | }, 27 | define: { 'process.env': {} }, 28 | plugins: [ 29 | vue(), 30 | ], 31 | resolve: { 32 | alias: { 33 | '@': path.resolve(__dirname, `./src`), 34 | }, 35 | }, 36 | server: { 37 | open: false, 38 | port: 9000, 39 | }, 40 | }); 41 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress'; 2 | import nav from './configs/nav'; 3 | import sidebar from './configs/sidebar'; 4 | 5 | export default defineConfig({ 6 | lang: 'en-US', 7 | title: 'Home', 8 | description: 'Documentation for vue-responsive-grid-layout component', 9 | appearance: true, 10 | lastUpdated: true, 11 | cleanUrls: 'true', 12 | 13 | base: process.env.BASE || '/', 14 | head: [['link', { 15 | rel: 'icon', 16 | type: 'image/svg+xml', 17 | href: '/Data Grid.svg' 18 | }]], 19 | // locales: { 20 | // root: { 21 | // label: 'English', 22 | // lang: 'en', 23 | // selectText: 'Languages', 24 | // }, 25 | // fr: { 26 | // label: 'French', 27 | // lang: 'fr', 28 | // link: '/fr/index', 29 | // selectText: 'Languages', 30 | // 31 | // // other locale specific properties... 32 | // } 33 | // }, 34 | 35 | markdown: { 36 | headers: { 37 | level: [0, 0], 38 | }, 39 | 40 | // options for markdown-it-anchor 41 | anchor: { permalink: false }, 42 | 43 | // options for markdown-it-toc 44 | toc: { includeLevel: [1, 2, 3] }, 45 | 46 | // theme: { 47 | // light: 'github-light', 48 | // dark: 'github-dark' 49 | // }, 50 | lineNumbers: true, 51 | }, 52 | 53 | themeConfig: { 54 | i18nRouting: true, 55 | logo: '/Data Grid.svg', 56 | lastUpdatedText: 'Updated', 57 | 58 | // algolia: { 59 | // appId: '', 60 | // apiKey: '', 61 | // indexName: 'vue-ts-responsive-grid-layout', 62 | // }, 63 | 64 | // nav 65 | nav, 66 | 67 | // sidebar 68 | sidebar, 69 | 70 | // editLink: { 71 | // pattern: 'https://github.com/gwinnem/admin-dashboard/edit/main/docs/:path', 72 | // text: 'Edit this page on GitHub', 73 | // }, 74 | 75 | socialLinks: [ 76 | { 77 | icon: 'github', 78 | link: 'https://github.com/gwinnem/vue-responsive-grid-layout' 79 | }, 80 | { 81 | icon: 'twitter', 82 | link: 'https://twitter.com/gwinnem' 83 | }, 84 | { 85 | icon: 'linkedin', 86 | link: 'https://www.linkedin.com/in/gwinnem/' 87 | }, 88 | { 89 | icon: { 90 | svg: '' 91 | }, 92 | link: 'https://www.xing.com/profile/Geirr_Winnem/cv' 93 | }, 94 | { 95 | icon: { 96 | svg: '' 97 | }, 98 | link: 'https://www.npmjs.com/package/vue-ts-responsive-grid-layout?activeTab=readme' 99 | } 100 | ], 101 | 102 | footer: { 103 | license: { 104 | text: 'MIT License', 105 | link: 'https://opensource.org/licenses/MIT' 106 | }, 107 | copyright: `Copyright © 2022-${new Date().getFullYear()} Geirr Winnem` 108 | } 109 | }, 110 | 111 | vite: { 112 | server: { 113 | host: true, 114 | port: 9091, 115 | }, 116 | json: { 117 | stringify: true, 118 | }, 119 | }, 120 | }); 121 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/configs/nav.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | text: 'Guide', 4 | link: '/guide/introduction', 5 | activeMatch: '^/guide/', 6 | }, 7 | { 8 | text: 'Features', 9 | link: '/features/', 10 | activeMatch: '^/features/' 11 | }, 12 | { 13 | text: 'Components', 14 | link: '/components/', 15 | activeMatch: '^/components/', 16 | }, 17 | { 18 | text: 'API', 19 | link: '/api/', 20 | activeMatch: '^/api/' 21 | }, 22 | { 23 | text: 'Examples', 24 | link: '/examples/01-example', 25 | activeMatch: '^/examples/', 26 | }, 27 | { 28 | text: 'Changelog', 29 | link: '/guide/changelog', 30 | activeMatch: '^/guide/', 31 | } 32 | ]; 33 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/Data Grid.svg: -------------------------------------------------------------------------------- 1 | 2 | Icons8 RSL Colored Part 10 3 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_GridItem-enums.md.CY87Ew73.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as e}from"./chunks/framework.DypzUre1.js";const c=JSON.parse('{"title":"EGridItemEvent","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"api/GridItem-enums.md","filePath":"api/GridItem-enums.md","lastUpdated":1703794519000}'),p={name:"api/GridItem-enums.md"};function l(t,s,h,k,r,d){return n(),a("div",null,s[0]||(s[0]=[e('

EGridItemEvent

typescript
/**\n * Events emitted by the GridItem component\n */\nexport enum EGridItemEvent {\n  CONTAINER_RESIZED = `container-resized`,\n  DRAG = `drag`,\n  DRAGGED = `dragged`,\n  MOVE = `move`,\n  MOVED = `moved`,\n  REMOVE_ITEM = `remove-grid-item`,\n  RESIZE = `resize`,\n  RESIZED = `resized`,\n}
',2)]))}const g=i(p,[["render",l]]);export{c as __pageData,g as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_GridItem-enums.md.CY87Ew73.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as e}from"./chunks/framework.DypzUre1.js";const c=JSON.parse('{"title":"EGridItemEvent","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"api/GridItem-enums.md","filePath":"api/GridItem-enums.md","lastUpdated":1703794519000}'),p={name:"api/GridItem-enums.md"};function l(t,s,h,k,r,d){return n(),a("div",null,s[0]||(s[0]=[e("",2)]))}const g=i(p,[["render",l]]);export{c as __pageData,g as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_GridLayout-enums.md.CAP8d5La.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as p}from"./chunks/framework.DypzUre1.js";const F=JSON.parse('{"title":"EGridLayoutEvent","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"api/GridLayout-enums.md","filePath":"api/GridLayout-enums.md","lastUpdated":1703794519000}'),l={name:"api/GridLayout-enums.md"};function e(t,s,h,k,r,d){return n(),a("div",null,s[0]||(s[0]=[p("",2)]))}const y=i(l,[["render",e]]);export{F as __pageData,y as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_index.md.C09OD24K.js: -------------------------------------------------------------------------------- 1 | import{_ as a,c as r,o as i,j as t}from"./chunks/framework.DypzUre1.js";const x=JSON.parse('{"title":"API","description":"","frontmatter":{},"headers":[],"relativePath":"api/index.md","filePath":"api/index.md","lastUpdated":1703794519000}'),n={name:"api/index.md"};function s(o,e,d,p,c,l){return i(),r("div",null,e[0]||(e[0]=[t("h1",{id:"api",tabindex:"-1"},"API",-1),t("h2",{id:"work-in-progress",tabindex:"-1"},"Work in progress",-1)]))}const _=a(n,[["render",s]]);export{x as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_index.md.C09OD24K.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as a,c as r,o as i,j as t}from"./chunks/framework.DypzUre1.js";const x=JSON.parse('{"title":"API","description":"","frontmatter":{},"headers":[],"relativePath":"api/index.md","filePath":"api/index.md","lastUpdated":1703794519000}'),n={name:"api/index.md"};function s(o,e,d,p,c,l){return i(),r("div",null,e[0]||(e[0]=[t("h1",{id:"api",tabindex:"-1"},"API",-1),t("h2",{id:"work-in-progress",tabindex:"-1"},"Work in progress",-1)]))}const _=a(n,[["render",s]]);export{x as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_interfaces-eventBus.md.BoVerJx7.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as e}from"./chunks/framework.DypzUre1.js";const E=JSON.parse('{"title":"Eventbus interfaces","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"api/interfaces-eventBus.md","filePath":"api/interfaces-eventBus.md","lastUpdated":1703794519000}'),t={name:"api/interfaces-eventBus.md"};function p(l,s,h,k,r,d){return n(),a("div",null,s[0]||(s[0]=[e(`

Eventbus interfaces

IEventsData

Defines the payload drag and resize events are emitting.

typescript
export interface IEventsData {
2 |   eventType: string | symbol;
3 |   h: number;
4 |   i: string | number;
5 |   w: number;
6 |   x: number;
7 |   y: number;
8 | }
`,4)]))}const g=i(t,[["render",p]]);export{E as __pageData,g as default}; 9 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_interfaces-eventBus.md.BoVerJx7.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as e}from"./chunks/framework.DypzUre1.js";const E=JSON.parse('{"title":"Eventbus interfaces","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"api/interfaces-eventBus.md","filePath":"api/interfaces-eventBus.md","lastUpdated":1703794519000}'),t={name:"api/interfaces-eventBus.md"};function p(l,s,h,k,r,d){return n(),a("div",null,s[0]||(s[0]=[e("",4)]))}const g=i(t,[["render",p]]);export{E as __pageData,g as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_interfaces-layout.md.BIyzYU9b.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as e}from"./chunks/framework.DypzUre1.js";const y=JSON.parse('{"title":"Layout interfaces","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"api/interfaces-layout.md","filePath":"api/interfaces-layout.md","lastUpdated":1703794519000}'),t={name:"api/interfaces-layout.md"};function p(l,s,h,r,k,d){return n(),a("div",null,s[0]||(s[0]=[e(`

Layout interfaces

ILayoutItemRequired

Defines the required properties for a grid layout.

typescript
export interface ILayoutItemRequired {
2 |   w: number;
3 |   h: number;
4 |   x: number;
5 |   y: number;
6 |   i: string | number;
7 | }
`,4)]))}const o=i(t,[["render",p]]);export{y as __pageData,o as default}; 8 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_interfaces-layout.md.BIyzYU9b.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as e}from"./chunks/framework.DypzUre1.js";const y=JSON.parse('{"title":"Layout interfaces","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"api/interfaces-layout.md","filePath":"api/interfaces-layout.md","lastUpdated":1703794519000}'),t={name:"api/interfaces-layout.md"};function p(l,s,h,r,k,d){return n(),a("div",null,s[0]||(s[0]=[e("",4)]))}const o=i(t,[["render",p]]);export{y as __pageData,o as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_types-layout.md.DLhsXbwC.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as t}from"./chunks/framework.DypzUre1.js";const o=JSON.parse('{"title":"Layout types","description":"","frontmatter":{},"headers":[],"relativePath":"api/types-layout.md","filePath":"api/types-layout.md","lastUpdated":1703794519000}'),e={name:"api/types-layout.md"};function p(l,s,h,k,r,d){return n(),a("div",null,s[0]||(s[0]=[t(`

Layout types

TLayoutItem

typescript
export type TLayoutItem = ILayoutItemRequired & {
 2 | minW?: number;
 3 | minH?: number;
 4 | maxW?: number;
 5 | maxH?: number;
 6 | moved?: boolean;
 7 | isStatic?: boolean;
 8 | isDraggable?: boolean;
 9 | isResizable?: boolean;
10 | }

TLayout

typescript
export type TLayout = TLayoutItem[]
`,5)]))}const c=i(e,[["render",p]]);export{o as __pageData,c as default}; 11 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/api_types-layout.md.DLhsXbwC.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as t}from"./chunks/framework.DypzUre1.js";const o=JSON.parse('{"title":"Layout types","description":"","frontmatter":{},"headers":[],"relativePath":"api/types-layout.md","filePath":"api/types-layout.md","lastUpdated":1703794519000}'),e={name:"api/types-layout.md"};function p(l,s,h,k,r,d){return n(),a("div",null,s[0]||(s[0]=[t("",5)]))}const c=i(e,[["render",p]]);export{o as __pageData,c as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/app.y2ni2aWa.js: -------------------------------------------------------------------------------- 1 | import{R as p}from"./chunks/theme.9tTlfeSW.js";import{R as s,a0 as i,a1 as u,a2 as c,a3 as l,a4 as f,a5 as d,a6 as m,a7 as h,a8 as g,a9 as A,d as v,u as R,v as w,s as y,aa as C,ab as P,ac as b,ad as E}from"./chunks/framework.DypzUre1.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),P(),b(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_css-grid-item.md.DVqyfjrg.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as p}from"./chunks/framework.DypzUre1.js";const g=JSON.parse('{"title":"GridItem styles","description":"","frontmatter":{},"headers":[],"relativePath":"components/css-grid-item.md","filePath":"components/css-grid-item.md","lastUpdated":1703794519000}'),l={name:"components/css-grid-item.md"};function h(k,s,t,e,r,E){return n(),a("div",null,s[0]||(s[0]=[p("",2)]))}const y=i(l,[["render",h]]);export{g as __pageData,y as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_css-grid-layout.md.OI24WuTh.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as t}from"./chunks/framework.DypzUre1.js";const c=JSON.parse('{"title":"GridLayout styles","description":"","frontmatter":{},"headers":[],"relativePath":"components/css-grid-layout.md","filePath":"components/css-grid-layout.md","lastUpdated":1703794519000}'),e={name:"components/css-grid-layout.md"};function l(p,s,r,h,d,k){return n(),a("div",null,s[0]||(s[0]=[t(`

GridLayout styles

scss
.vue-grid-layout {
2 |   position: relative;
3 |   transition: height 200ms ease;
4 | }
`,2)]))}const g=i(e,[["render",l]]);export{c as __pageData,g as default}; 5 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_css-grid-layout.md.OI24WuTh.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as t}from"./chunks/framework.DypzUre1.js";const c=JSON.parse('{"title":"GridLayout styles","description":"","frontmatter":{},"headers":[],"relativePath":"components/css-grid-layout.md","filePath":"components/css-grid-layout.md","lastUpdated":1703794519000}'),e={name:"components/css-grid-layout.md"};function l(p,s,r,h,d,k){return n(),a("div",null,s[0]||(s[0]=[t("",2)]))}const g=i(e,[["render",l]]);export{c as __pageData,g as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_css-variables.md.COUjaV5E.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as e,ae as t}from"./chunks/framework.DypzUre1.js";const k=JSON.parse('{"title":"Variables","description":"","frontmatter":{},"headers":[],"relativePath":"components/css-variables.md","filePath":"components/css-variables.md","lastUpdated":1703794519000}'),n={name:"components/css-variables.md"};function d(l,s,r,p,h,c){return e(),a("div",null,s[0]||(s[0]=[t("",17)]))}const g=i(n,[["render",d]]);export{k as __pageData,g as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-item-event-bus-events.md.C2MZog7y.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as n,o as d,ae as i}from"./chunks/framework.DypzUre1.js";const l=JSON.parse('{"title":"GridItem Eventbus Events","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-item-event-bus-events.md","filePath":"components/grid-item-event-bus-events.md","lastUpdated":1703794519000}'),a={name:"components/grid-item-event-bus-events.md"};function s(r,e,o,h,c,m){return d(),n("div",null,e[0]||(e[0]=[i('

GridItem Eventbus Events

compact

directionchange

dragEvent

  • Emitted in handleDrag, the event handler for drag events.

resizeEvent

setBounded

setColNum

setDraggable

setMaxRows

setResizable

setRowHeight

setTransformScale

updateWidth

',14)]))}const v=t(a,[["render",s]]);export{l as __pageData,v as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-item-event-bus-events.md.C2MZog7y.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as n,o as d,ae as i}from"./chunks/framework.DypzUre1.js";const l=JSON.parse('{"title":"GridItem Eventbus Events","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-item-event-bus-events.md","filePath":"components/grid-item-event-bus-events.md","lastUpdated":1703794519000}'),a={name:"components/grid-item-event-bus-events.md"};function s(r,e,o,h,c,m){return d(),n("div",null,e[0]||(e[0]=[i("",14)]))}const v=t(a,[["render",s]]);export{l as __pageData,v as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-item-events.md.C01h7Wp8.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as h}from"./chunks/framework.DypzUre1.js";const g=JSON.parse('{"title":"GridItem VUE Events","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-item-events.md","filePath":"components/grid-item-events.md","lastUpdated":1726146329000}'),t={name:"components/grid-item-events.md"};function k(e,s,p,l,E,r){return n(),a("div",null,s[0]||(s[0]=[h("",30)]))}const y=i(t,[["render",k]]);export{g as __pageData,y as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-item-props.md.INyiBBAx.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as o,o as t,ae as d}from"./chunks/framework.DypzUre1.js";const p=JSON.parse('{"title":"GridItem Properties","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-item-props.md","filePath":"components/grid-item-props.md","lastUpdated":1703794519000}'),l={name:"components/grid-item-props.md"};function r(a,e,c,n,s,h){return t(),o("div",null,e[0]||(e[0]=[d("",97)]))}const m=i(l,[["render",r]]);export{p as __pageData,m as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-item-slots.md.upPuBDGJ.js: -------------------------------------------------------------------------------- 1 | import{_ as s,c as o,o as a,j as t,a as r}from"./chunks/framework.DypzUre1.js";const f=JSON.parse('{"title":"GridItem slots","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-item-slots.md","filePath":"components/grid-item-slots.md","lastUpdated":1703794519000}'),l={name:"components/grid-item-slots.md"};function n(i,e,d,m,c,p){return a(),o("div",null,e[0]||(e[0]=[t("h1",{id:"griditem-slots",tabindex:"-1"},"GridItem slots",-1),t("ul",null,[t("li",null,[t("strong",null,"Default slot"),r(".")])],-1)]))}const _=s(l,[["render",n]]);export{f as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-item-slots.md.upPuBDGJ.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as s,c as o,o as a,j as t,a as r}from"./chunks/framework.DypzUre1.js";const f=JSON.parse('{"title":"GridItem slots","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-item-slots.md","filePath":"components/grid-item-slots.md","lastUpdated":1703794519000}'),l={name:"components/grid-item-slots.md"};function n(i,e,d,m,c,p){return a(),o("div",null,e[0]||(e[0]=[t("h1",{id:"griditem-slots",tabindex:"-1"},"GridItem slots",-1),t("ul",null,[t("li",null,[t("strong",null,"Default slot"),r(".")])],-1)]))}const _=s(l,[["render",n]]);export{f as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-item.md.CPAgr0Y6.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as r,o as a,j as o}from"./chunks/framework.DypzUre1.js";const _=JSON.parse('{"title":"GridItem","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-item.md","filePath":"components/grid-item.md","lastUpdated":1703794519000}'),i={name:"components/grid-item.md"};function n(d,e,s,m,c,p){return a(),r("div",null,e[0]||(e[0]=[o("h1",{id:"griditem",tabindex:"-1"},"GridItem",-1)]))}const f=t(i,[["render",n]]);export{_ as __pageData,f as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-item.md.CPAgr0Y6.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as r,o as a,j as o}from"./chunks/framework.DypzUre1.js";const _=JSON.parse('{"title":"GridItem","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-item.md","filePath":"components/grid-item.md","lastUpdated":1703794519000}'),i={name:"components/grid-item.md"};function n(d,e,s,m,c,p){return a(),r("div",null,e[0]||(e[0]=[o("h1",{id:"griditem",tabindex:"-1"},"GridItem",-1)]))}const f=t(i,[["render",n]]);export{_ as __pageData,f as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-layout-event-bus-events.md.CR5IuVtB.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as a,o as d,ae as i}from"./chunks/framework.DypzUre1.js";const m=JSON.parse('{"title":"GridLayout eventBus Events","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-layout-event-bus-events.md","filePath":"components/grid-layout-event-bus-events.md","lastUpdated":1703794519000}'),n={name:"components/grid-layout-event-bus-events.md"};function s(o,e,r,l,u,c){return d(),a("div",null,e[0]||(e[0]=[i('

GridLayout eventBus Events

compact

  • Emitted during drag after layout is compacted.
  • Emitted during resize after layout is compacted.

dragEvent

  • Forwarding dragEvent emitted from the GridItem component.

resizeEvent

setBounded

setColNum

setDraggable

setMaxRows

setResizable

setRowHeight

setTransformScale

updateWidth

',14)]))}const p=t(n,[["render",s]]);export{m as __pageData,p as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-layout-event-bus-events.md.CR5IuVtB.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as a,o as d,ae as i}from"./chunks/framework.DypzUre1.js";const m=JSON.parse('{"title":"GridLayout eventBus Events","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-layout-event-bus-events.md","filePath":"components/grid-layout-event-bus-events.md","lastUpdated":1703794519000}'),n={name:"components/grid-layout-event-bus-events.md"};function s(o,e,r,l,u,c){return d(),a("div",null,e[0]||(e[0]=[i("",14)]))}const p=t(n,[["render",s]]);export{m as __pageData,p as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-layout-events.md.BH8KhKvS.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as t,ae as n}from"./chunks/framework.DypzUre1.js";const E=JSON.parse('{"title":"GridLayout VUE Events","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-layout-events.md","filePath":"components/grid-layout-events.md","lastUpdated":1703794519000}'),e={name:"components/grid-layout-events.md"};function p(h,s,l,d,k,r){return t(),a("div",null,s[0]||(s[0]=[n("",31)]))}const y=i(e,[["render",p]]);export{E as __pageData,y as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-layout-props.md.vNbBkqP9.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as o,c as i,o as d,ae as l}from"./chunks/framework.DypzUre1.js";const p=JSON.parse('{"title":"GridLayout Properties","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-layout-props.md","filePath":"components/grid-layout-props.md","lastUpdated":1703794519000}'),t={name:"components/grid-layout-props.md"};function a(c,e,r,s,u,n){return d(),i("div",null,e[0]||(e[0]=[l("",83)]))}const f=o(t,[["render",a]]);export{p as __pageData,f as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-layout.md.CBRPOZKi.js: -------------------------------------------------------------------------------- 1 | import{_ as e,c as a,o,j as r}from"./chunks/framework.DypzUre1.js";const u=JSON.parse('{"title":"GridLayout","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-layout.md","filePath":"components/grid-layout.md","lastUpdated":1703794519000}'),n={name:"components/grid-layout.md"};function d(s,t,i,c,p,l){return o(),a("div",null,t[0]||(t[0]=[r("h1",{id:"gridlayout",tabindex:"-1"},"GridLayout",-1)]))}const _=e(n,[["render",d]]);export{u as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_grid-layout.md.CBRPOZKi.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as e,c as a,o,j as r}from"./chunks/framework.DypzUre1.js";const u=JSON.parse('{"title":"GridLayout","description":"","frontmatter":{},"headers":[],"relativePath":"components/grid-layout.md","filePath":"components/grid-layout.md","lastUpdated":1703794519000}'),n={name:"components/grid-layout.md"};function d(s,t,i,c,p,l){return o(),a("div",null,t[0]||(t[0]=[r("h1",{id:"gridlayout",tabindex:"-1"},"GridLayout",-1)]))}const _=e(n,[["render",d]]);export{u as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_index.md.B3_E7yWG.js: -------------------------------------------------------------------------------- 1 | import{_ as o,c as l,o as s,j as e,a as t}from"./chunks/framework.DypzUre1.js";const f=JSON.parse('{"title":"Features","description":"","frontmatter":{"aside":true,"page":true,"title":"Features"},"headers":[],"relativePath":"components/index.md","filePath":"components/index.md","lastUpdated":1703794519000}'),a={name:"components/index.md"};function i(d,n,r,u,c,p){return s(),l("div",null,n[0]||(n[0]=[e("h1",{id:"components",tabindex:"-1"},"Components",-1),e("p",null,"This plugin is exporting the following components:",-1),e("ul",null,[e("li",null,[e("code",null,"GridLayout"),t(", Defines the main grid layout.")]),e("li",null,[e("code",null,"GridItem"),t(" Defines an item in the layout.")]),e("li",null,[e("code",null,"CustomCloseButton"),t(" Customized close button.")])],-1)]))}const x=o(a,[["render",i]]);export{f as __pageData,x as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/components_index.md.B3_E7yWG.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as o,c as l,o as s,j as e,a as t}from"./chunks/framework.DypzUre1.js";const f=JSON.parse('{"title":"Features","description":"","frontmatter":{"aside":true,"page":true,"title":"Features"},"headers":[],"relativePath":"components/index.md","filePath":"components/index.md","lastUpdated":1703794519000}'),a={name:"components/index.md"};function i(d,n,r,u,c,p){return s(),l("div",null,n[0]||(n[0]=[e("h1",{id:"components",tabindex:"-1"},"Components",-1),e("p",null,"This plugin is exporting the following components:",-1),e("ul",null,[e("li",null,[e("code",null,"GridLayout"),t(", Defines the main grid layout.")]),e("li",null,[e("code",null,"GridItem"),t(" Defines an item in the layout.")]),e("li",null,[e("code",null,"CustomCloseButton"),t(" Customized close button.")])],-1)]))}const x=o(a,[["render",i]]);export{f as __pageData,x as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/examples_09-example.md.jwyUjZI3.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as a,o as s,j as p}from"./chunks/framework.DypzUre1.js";const f=JSON.parse('{"title":"Responsive with predefined layouts.","description":"","frontmatter":{},"headers":[],"relativePath":"examples/09-example.md","filePath":"examples/09-example.md","lastUpdated":1703794519000}'),o={name:"examples/09-example.md"};function n(r,e,d,i,l,m){return s(),a("div",null,e[0]||(e[0]=[p("h1",{id:"responsive-with-predefined-layouts",tabindex:"-1"},"Responsive with predefined layouts.",-1)]))}const x=t(o,[["render",n]]);export{f as __pageData,x as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/examples_09-example.md.jwyUjZI3.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as a,o as s,j as p}from"./chunks/framework.DypzUre1.js";const f=JSON.parse('{"title":"Responsive with predefined layouts.","description":"","frontmatter":{},"headers":[],"relativePath":"examples/09-example.md","filePath":"examples/09-example.md","lastUpdated":1703794519000}'),o={name:"examples/09-example.md"};function n(r,e,d,i,l,m){return s(),a("div",null,e[0]||(e[0]=[p("h1",{id:"responsive-with-predefined-layouts",tabindex:"-1"},"Responsive with predefined layouts.",-1)]))}const x=t(o,[["render",n]]);export{f as __pageData,x as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/examples_12-example.md.Dd7bFAZb.js: -------------------------------------------------------------------------------- 1 | import{_ as a,c as t,o as r,j as s}from"./chunks/framework.DypzUre1.js";const x=JSON.parse('{"title":"Drag & Drop between Grid layouts.","description":"","frontmatter":{},"headers":[],"relativePath":"examples/12-example.md","filePath":"examples/12-example.md","lastUpdated":1703794519000}'),o={name:"examples/12-example.md"};function p(d,e,l,n,m,i){return r(),t("div",null,e[0]||(e[0]=[s("h1",{id:"drag-drop-between-grid-layouts",tabindex:"-1"},"Drag & Drop between Grid layouts.",-1)]))}const _=a(o,[["render",p]]);export{x as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/examples_12-example.md.Dd7bFAZb.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as a,c as t,o as r,j as s}from"./chunks/framework.DypzUre1.js";const x=JSON.parse('{"title":"Drag & Drop between Grid layouts.","description":"","frontmatter":{},"headers":[],"relativePath":"examples/12-example.md","filePath":"examples/12-example.md","lastUpdated":1703794519000}'),o={name:"examples/12-example.md"};function p(d,e,l,n,m,i){return r(),t("div",null,e[0]||(e[0]=[s("h1",{id:"drag-drop-between-grid-layouts",tabindex:"-1"},"Drag & Drop between Grid layouts.",-1)]))}const _=a(o,[["render",p]]);export{x as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/features_index.md.AHctw1-D.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as t,o as r,ae as a}from"./chunks/framework.DypzUre1.js";const p=JSON.parse('{"title":"Features","description":"","frontmatter":{"aside":false,"page":true,"title":"Features"},"headers":[],"relativePath":"features/index.md","filePath":"features/index.md","lastUpdated":1703794519000}'),l={name:"features/index.md"};function s(d,e,o,n,u,c){return r(),t("div",null,e[0]||(e[0]=[a('

Features

  • VUE 3 with Typescript.
  • Vite used as dev server and bundler.
  • Vitepress used for documentation.
  • Automatic responsiveness with breakpoints configuration.
  • GridItem Border Radius.
  • GridLayout Edit Mode.
  • Horizontal Shift.
  • Close button in GridItem.
  • New Test application, styled with mini.css.
  • Cursor styling.
  • Fixed mirrored layout so only the GridItems are rearranged.
  • Draggable widgets.
  • Resizable widgets.
  • Static widgets.
  • Bounds checking for dragging and resizing.
  • Widgets may be added or removed without rebuilding grid.
  • Layout can be serialized and restored.
  • Responsive with predefined Layouts.
  • Grid items are distributed evenly.
  • Grid item is resizable from right, bottom right and bottom.
',2)]))}const _=i(l,[["render",s]]);export{p as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/features_index.md.AHctw1-D.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as t,o as r,ae as a}from"./chunks/framework.DypzUre1.js";const p=JSON.parse('{"title":"Features","description":"","frontmatter":{"aside":false,"page":true,"title":"Features"},"headers":[],"relativePath":"features/index.md","filePath":"features/index.md","lastUpdated":1703794519000}'),l={name:"features/index.md"};function s(d,e,o,n,u,c){return r(),t("div",null,e[0]||(e[0]=[a("",2)]))}const _=i(l,[["render",s]]);export{p as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/guide_changelog.md.gv5YiFNR.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as r,o as i,ae as n}from"./chunks/framework.DypzUre1.js";const p=JSON.parse('{"title":"Changelog","description":"","frontmatter":{"aside":false,"footer":true,"page":true,"title":"Changelog"},"headers":[],"relativePath":"guide/changelog.md","filePath":"guide/changelog.md","lastUpdated":1707232468000}'),s={name:"guide/changelog.md"};function o(a,e,g,l,d,u){return i(),r("div",null,e[0]||(e[0]=[n("",20)]))}const m=t(s,[["render",o]]);export{p as __pageData,m as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/guide_installation.md.BteGI3qK.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as e}from"./chunks/framework.DypzUre1.js";const c=JSON.parse('{"title":"Installation","description":"","frontmatter":{"page":true,"title":"Installation"},"headers":[],"relativePath":"guide/installation.md","filePath":"guide/installation.md","lastUpdated":1703794519000}'),t={name:"guide/installation.md"};function p(l,s,r,d,h,o){return n(),a("div",null,s[0]||(s[0]=[e(`

Installation

NPM

	npm install vue-ts-responsive-grid-layout --save

Yarn

    yarn add vue-ts-responsive-grid-layout

Import the package

typescript
    import VueResponsiveGridLayout from 'vue-ts-responsive-grid-layout';

Add to other Vue components using Options api.

typescript
    export default {
 2 |         components: {
 3 |             GridLayout: VueResponsiveGridLayout.GridLayout,
 4 |             GridItem: VueResponsiveGridLayout.GridItem
 5 |         },
 6 |     // ... data, methods, mounted (), etc.
 7 |     }

Add to other Vue components using Composition api.

html
<script setup>
 8 |   import { GridItem, GridLayout } from 'vue-ts-responsive-grid-layout';
 9 | </script>
`,11)]))}const u=i(t,[["render",p]]);export{c as __pageData,u as default}; 10 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/guide_installation.md.BteGI3qK.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as i,c as a,o as n,ae as e}from"./chunks/framework.DypzUre1.js";const c=JSON.parse('{"title":"Installation","description":"","frontmatter":{"page":true,"title":"Installation"},"headers":[],"relativePath":"guide/installation.md","filePath":"guide/installation.md","lastUpdated":1703794519000}'),t={name:"guide/installation.md"};function p(l,s,r,d,h,o){return n(),a("div",null,s[0]||(s[0]=[e("",11)]))}const u=i(t,[["render",p]]);export{c as __pageData,u as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/guide_introduction.md.BDS_NV86.js: -------------------------------------------------------------------------------- 1 | import{_ as o,c as a,o as n,j as e}from"./chunks/framework.DypzUre1.js";const f=JSON.parse('{"title":"Introduction","description":"","frontmatter":{"aside":false,"footer":true,"page":true,"title":"Introduction"},"headers":[],"relativePath":"guide/introduction.md","filePath":"guide/introduction.md","lastUpdated":1703794519000}'),r={name:"guide/introduction.md"};function i(s,t,d,u,c,p){return n(),a("div",null,t[0]||(t[0]=[e("h1",{id:"what-is-vue-ts-responsive-grid-layout",tabindex:"-1"},"What is vue-ts-responsive-grid-layout?",-1),e("p",null,"A responsive grid layout component for creating advance dashboard's.",-1)]))}const m=o(r,[["render",i]]);export{f as __pageData,m as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/guide_introduction.md.BDS_NV86.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as o,c as a,o as n,j as e}from"./chunks/framework.DypzUre1.js";const f=JSON.parse('{"title":"Introduction","description":"","frontmatter":{"aside":false,"footer":true,"page":true,"title":"Introduction"},"headers":[],"relativePath":"guide/introduction.md","filePath":"guide/introduction.md","lastUpdated":1703794519000}'),r={name:"guide/introduction.md"};function i(s,t,d,u,c,p){return n(),a("div",null,t[0]||(t[0]=[e("h1",{id:"what-is-vue-ts-responsive-grid-layout",tabindex:"-1"},"What is vue-ts-responsive-grid-layout?",-1),e("p",null,"A responsive grid layout component for creating advance dashboard's.",-1)]))}const m=o(r,[["render",i]]);export{f as __pageData,m as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/guide_roadmap.md.9TcX4Dlx.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as r,o,ae as s}from"./chunks/framework.DypzUre1.js";const u=JSON.parse('{"title":"Roadmap","description":"","frontmatter":{"aside":false,"footer":true,"page":true,"title":"Roadmap"},"headers":[],"relativePath":"guide/roadmap.md","filePath":"guide/roadmap.md","lastUpdated":1706894553000}'),i={name:"guide/roadmap.md"};function a(n,e,d,l,p,g){return o(),r("div",null,e[0]||(e[0]=[s('

ROADMAP

Upcoming updates and fixes

  • New Feature Implement resize from left side.
  • New Feature Implement resize from top-left side.
  • New Feature Implement resize from bottom-left side.
  • New Feature Drag & Drop from Multiple Grids.
  • New Feature Add native drag and drop to GridLayout.
  • New Feature Add possibility to set fixed width on a GridItem.
  • New Feature Add pre styled GridItem.
  • New Feature Implement RTL resize.
  • New Feature Support for nuxt projects.
  • Examples Dynamic add new GridItems.
  • Examples Add example app to CodeSandbox, so user's can test layouts.
  • Examples Add Multiple Grids.
  • Examples Add Responsive predefined layouts.
  • Examples Drag, drop from grid to grid.
  • Test Add e2e tests.
  • Test Continuously refactoring and adding new unit tests.
',3)]))}const f=t(i,[["render",a]]);export{u as __pageData,f as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/guide_roadmap.md.9TcX4Dlx.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as t,c as r,o,ae as s}from"./chunks/framework.DypzUre1.js";const u=JSON.parse('{"title":"Roadmap","description":"","frontmatter":{"aside":false,"footer":true,"page":true,"title":"Roadmap"},"headers":[],"relativePath":"guide/roadmap.md","filePath":"guide/roadmap.md","lastUpdated":1706894553000}'),i={name:"guide/roadmap.md"};function a(n,e,d,l,p,g){return o(),r("div",null,e[0]||(e[0]=[s("",3)]))}const f=t(i,[["render",a]]);export{u as __pageData,f as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/index.md.VCkZeN5U.js: -------------------------------------------------------------------------------- 1 | import{_ as e,c as t,o as a}from"./chunks/framework.DypzUre1.js";const m=JSON.parse(`{"title":"Vue 3 Responsive Grid Layout.","titleTemplate":"Main","description":"","frontmatter":{"layout":"home","title":"Vue 3 Responsive Grid Layout.","titleTemplate":"Main","hero":{"name":"Vue 3 Responsive Grid Layout.","tagline":"Draggable, Resizeable widgets.","image":{"src":"/Data Grid.svg","alt":"logo"},"actions":[{"theme":"brand","text":"Get Started","link":"/guide/introduction"}]},"features":[{"icon":"⚡️","title":"Latest Release version","details":"1.2.10 Released 2025-04-28."},{"icon":"💥","title":"Responsive Grid Layouts","details":"With predefined layout's or automatically with predefined breakpoints."},{"icon":"🔱","title":"Draggable GridItems","details":"Examples showing howto Drag and Drop a GridItem."},{"icon":"🔱","title":"Resizeable GridItems","details":"Constantly being updated for each release.."}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1706887096000}`),i={name:"index.md"};function s(o,n,r,d,l,c){return a(),t("div")}const u=e(i,[["render",s]]);export{m as __pageData,u as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/index.md.VCkZeN5U.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as e,c as t,o as a}from"./chunks/framework.DypzUre1.js";const m=JSON.parse(`{"title":"Vue 3 Responsive Grid Layout.","titleTemplate":"Main","description":"","frontmatter":{"layout":"home","title":"Vue 3 Responsive Grid Layout.","titleTemplate":"Main","hero":{"name":"Vue 3 Responsive Grid Layout.","tagline":"Draggable, Resizeable widgets.","image":{"src":"/Data Grid.svg","alt":"logo"},"actions":[{"theme":"brand","text":"Get Started","link":"/guide/introduction"}]},"features":[{"icon":"⚡️","title":"Latest Release version","details":"1.2.10 Released 2025-04-28."},{"icon":"💥","title":"Responsive Grid Layouts","details":"With predefined layout's or automatically with predefined breakpoints."},{"icon":"🔱","title":"Draggable GridItems","details":"Examples showing howto Drag and Drop a GridItem."},{"icon":"🔱","title":"Resizeable GridItems","details":"Constantly being updated for each release.."}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1706887096000}`),i={name:"index.md"};function s(o,n,r,d,l,c){return a(),t("div")}const u=e(i,[["render",s]]);export{m as __pageData,u as default}; 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwinnem/vue-responsive-grid-layout/8ec736f793ee6b9a68bce43beae0c26a2e96268c/vitepress-docs/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/hashmap.json: -------------------------------------------------------------------------------- 1 | {"api_griditem-enums.md":"CY87Ew73","api_gridlayout-enums.md":"CAP8d5La","api_index.md":"C09OD24K","api_interfaces-eventbus.md":"BoVerJx7","api_interfaces-layout.md":"BIyzYU9b","api_types-layout.md":"DLhsXbwC","components_css-grid-item.md":"DVqyfjrg","components_css-grid-layout.md":"OI24WuTh","components_css-variables.md":"COUjaV5E","components_grid-item-event-bus-events.md":"C2MZog7y","components_grid-item-events.md":"C01h7Wp8","components_grid-item-props.md":"INyiBBAx","components_grid-item-slots.md":"upPuBDGJ","components_grid-item.md":"CPAgr0Y6","components_grid-layout-event-bus-events.md":"CR5IuVtB","components_grid-layout-events.md":"BH8KhKvS","components_grid-layout-props.md":"vNbBkqP9","components_grid-layout.md":"CBRPOZKi","components_index.md":"B3_E7yWG","examples_01-example.md":"CpjcLeXb","examples_02-example.md":"xdK61rcG","examples_03-example.md":"O0pf15mA","examples_04-example.md":"B5gHf5UO","examples_05-example.md":"BVq1nHsn","examples_06-example.md":"zBUYEgBC","examples_07-example.md":"DkuN5EO6","examples_08-example.md":"oavXhDbg","examples_09-example.md":"jwyUjZI3","examples_10-example.md":"i1jm-6wQ","examples_11-example.md":"CHPw_daE","examples_12-example.md":"Dd7bFAZb","examples_13-example.md":"CTOGm0qH","examples_14-example.md":"DYMAMF7j","examples_15-example.md":"BeqmslxU","examples_16-example.md":"BeSdN6RY","features_index.md":"AHctw1-D","guide_changelog.md":"gv5YiFNR","guide_installation.md":"BteGI3qK","guide_introduction.md":"BDS_NV86","guide_roadmap.md":"9TcX4Dlx","index.md":"VCkZeN5U"} 2 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/npm-square-red.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/dist/vp-icons.css: -------------------------------------------------------------------------------- 1 | .vpi-social-github{--icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}.vpi-social-linkedin{--icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z'/%3E%3C/svg%3E")}.vpi-social-twitter{--icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M21.543 7.104c.015.211.015.423.015.636c0 6.507-4.954 14.01-14.01 14.01v-.003A13.94 13.94 0 0 1 0 19.539a9.88 9.88 0 0 0 7.287-2.041a4.93 4.93 0 0 1-4.6-3.42a4.9 4.9 0 0 0 2.223-.084A4.926 4.926 0 0 1 .96 9.167v-.062a4.9 4.9 0 0 0 2.235.616A4.93 4.93 0 0 1 1.67 3.148a13.98 13.98 0 0 0 10.15 5.144a4.929 4.929 0 0 1 8.39-4.49a9.9 9.9 0 0 0 3.128-1.196a4.94 4.94 0 0 1-2.165 2.724A9.8 9.8 0 0 0 24 4.555a10 10 0 0 1-2.457 2.549'/%3E%3C/svg%3E")} -------------------------------------------------------------------------------- /vitepress-docs/.vitepress/theme/index.js: -------------------------------------------------------------------------------- 1 | import DefaultTheme from 'vitepress/theme'; 2 | import './styles/index.css'; 3 | 4 | export default { 5 | ...DefaultTheme, 6 | enhanceApp(ctx) { 7 | DefaultTheme.enhanceApp(ctx); 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /vitepress-docs/api/GridItem-enums.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # EGridItemEvent 6 | 7 | ```typescript 8 | /** 9 | * Events emitted by the GridItem component 10 | */ 11 | export enum EGridItemEvent { 12 | CONTAINER_RESIZED = `container-resized`, 13 | DRAG = `drag`, 14 | DRAGGED = `dragged`, 15 | MOVE = `move`, 16 | MOVED = `moved`, 17 | REMOVE_ITEM = `remove-grid-item`, 18 | RESIZE = `resize`, 19 | RESIZED = `resized`, 20 | } 21 | ``` 22 | -------------------------------------------------------------------------------- /vitepress-docs/api/GridLayout-enums.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # EGridLayoutEvent 6 | 7 | ```typescript 8 | /** 9 | * Events emitted by the GridLayout component 10 | */ 11 | export enum EGridLayoutEvent { 12 | BREAKPOINT_CHANGED = `breakpoint-changed`, 13 | CHANGED_DIRECTION = `changed-direction`, 14 | COLUMNS_CHANGED = `columns-changed`, 15 | CONTAINER_RESIZED = `container-resized`, 16 | DRAG_END = `drag-end`, 17 | DRAG_MOVE= `drag-move`, 18 | DRAG_START = `drag-start`, 19 | LAYOUT_BEFORE_MOUNT = `layout-before-mount`, 20 | LAYOUT_CREATED = `layout-created`, 21 | LAYOUT_MOUNTED = `layout-mounted`, 22 | LAYOUT_READY = `layout-ready`, 23 | LAYOUT_UPDATED = `layout-updated`, 24 | LAYOUT_UPDATE = `layout-update`, 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /vitepress-docs/api/index.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | ## Work in progress 4 | -------------------------------------------------------------------------------- /vitepress-docs/api/interfaces-eventBus.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # Eventbus interfaces 6 | 7 | ## IEventsData 8 | Defines the payload `drag` and `resize` events are emitting. 9 | 10 | ```typescript 11 | export interface IEventsData { 12 | eventType: string | symbol; 13 | h: number; 14 | i: string | number; 15 | w: number; 16 | x: number; 17 | y: number; 18 | } 19 | ``` 20 | -------------------------------------------------------------------------------- /vitepress-docs/api/interfaces-layout.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # Layout interfaces 6 | 7 | ## ILayoutItemRequired 8 | 9 | Defines the required properties for a grid layout. 10 | 11 | ```typescript 12 | export interface ILayoutItemRequired { 13 | w: number; 14 | h: number; 15 | x: number; 16 | y: number; 17 | i: string | number; 18 | } 19 | ``` 20 | -------------------------------------------------------------------------------- /vitepress-docs/api/types-layout.md: -------------------------------------------------------------------------------- 1 | # Layout types 2 | 3 | 4 | ## `TLayoutItem` 5 | ```typescript 6 | export type TLayoutItem = ILayoutItemRequired & { 7 | minW?: number; 8 | minH?: number; 9 | maxW?: number; 10 | maxH?: number; 11 | moved?: boolean; 12 | isStatic?: boolean; 13 | isDraggable?: boolean; 14 | isResizable?: boolean; 15 | } 16 | ``` 17 | 18 | ## `TLayout` 19 | ```typescript 20 | export type TLayout = TLayoutItem[] 21 | ``` 22 | -------------------------------------------------------------------------------- /vitepress-docs/components/css-grid-item.md: -------------------------------------------------------------------------------- 1 | # GridItem styles 2 | 3 | ```scss 4 | @import '../../styles/variables'; 5 | 6 | $grid-item-border-radius: 10px; 7 | 8 | .vue-close-button { 9 | height: 24px; 10 | position: absolute; 11 | right: 3px; 12 | top: 3px; 13 | width: 24px; 14 | z-index: 20; 15 | } 16 | 17 | .vue-close-button:hover { 18 | cursor: pointer; 19 | filter: brightness(0) invert(1); 20 | opacity: .8; 21 | } 22 | 23 | .vue-grid-item { 24 | background-color: $grid-item-bg-color; 25 | box-sizing: border-box; 26 | color: $grid-item-text-color; 27 | cursor: default !important; 28 | font-size: $grid-item-font-size; 29 | touch-action: none; 30 | transition: all 200ms ease; 31 | transition-property: left, top, right; 32 | 33 | &.vue-static { 34 | background-color: $grid-item-static-bg-color; 35 | } 36 | 37 | &.no-touch { 38 | touch-action: none; 39 | } 40 | 41 | &.vue-use-radius { 42 | border-radius: $grid-item-border-radius; 43 | } 44 | 45 | &.css-transforms { 46 | left: 0; 47 | right: auto; 48 | transition-property: transform; 49 | } 50 | 51 | &.resizing { 52 | opacity: .6; 53 | z-index: 3; 54 | } 55 | 56 | &.vue-draggable { 57 | cursor: grab !important; 58 | } 59 | 60 | &.vue-draggable-dragging { 61 | cursor: grabbing !important; 62 | transition: none; 63 | z-index: 3; 64 | } 65 | 66 | &.vue-grid-placeholder { 67 | background: $grid-item-placeholder-bg-color; 68 | opacity: $grid-item-placeholder-opacity; 69 | transition-duration: 100ms; 70 | user-select: none; 71 | z-index: 2; 72 | } 73 | 74 | & > .vue-resizable-handle { 75 | background-image: url('../../assets/resize.svg'); 76 | background-origin: content-box; 77 | background-position: bottom right; 78 | background-repeat: no-repeat; 79 | bottom: 1px; 80 | box-sizing: border-box; 81 | cursor: se-resize; 82 | height: 20px; 83 | padding: 0 3px 3px 0; 84 | position: absolute; 85 | right: 1px; 86 | width: 20px; 87 | z-index: 20; 88 | } 89 | 90 | &.disable-user-select { 91 | user-select: none; 92 | } 93 | } 94 | ``` 95 | -------------------------------------------------------------------------------- /vitepress-docs/components/css-grid-layout.md: -------------------------------------------------------------------------------- 1 | # GridLayout styles 2 | 3 | ```scss 4 | .vue-grid-layout { 5 | position: relative; 6 | transition: height 200ms ease; 7 | } 8 | ``` 9 | -------------------------------------------------------------------------------- /vitepress-docs/components/css-variables.md: -------------------------------------------------------------------------------- 1 | # Variables 2 | 3 | ## GridLayout grid-lines 4 | ```scss 5 | $grid-line-color: #000; 6 | ``` 7 | 8 | 9 | ## GridItem `background-color` 10 | ```scss 11 | $grid-item-bg-color: #720c0c; 12 | ``` 13 | 14 | 15 | ## GridItem default `border-radius`. 16 | ```sass 17 | $grid-item-border-radius: 8px; 18 | ``` 19 | 20 | ## TBD 21 | ```scss 22 | $grid-item-text-color: white; 23 | ``` 24 | 25 | 26 | ## TBD 27 | ```scss 28 | $grid-item-font-size: 1rem; 29 | ``` 30 | 31 | 32 | ## GridItem `background-color` used when a GridItem has the `isStatic` prop set to `true`. 33 | ```scss 34 | $grid-item-static-bg-color: #393d42; 35 | ``` 36 | 37 | 38 | ## GridItem `background-color` used for the displayed dragging GridItem. 39 | ```scss 40 | $grid-item-placeholder-bg-color: red; 41 | ``` 42 | 43 | 44 | ## GridItem `opacity` used for the displayed dragging GridItem. 45 | ```scss 46 | $grid-item-placeholder-opacity: .5; 47 | ``` 48 | -------------------------------------------------------------------------------- /vitepress-docs/components/grid-item-event-bus-events.md: -------------------------------------------------------------------------------- 1 | # GridItem Eventbus Events 2 | 3 | ## compact 4 | 5 | 6 | ## directionchange 7 | 8 | 9 | ## dragEvent 10 | * Emitted in `handleDrag`, the event handler for drag events. 11 | 12 | 13 | ## resizeEvent 14 | 15 | 16 | ## setBounded 17 | 18 | 19 | ## setColNum 20 | 21 | 22 | ## setDraggable 23 | 24 | 25 | ## setMaxRows 26 | 27 | 28 | ## setResizable 29 | 30 | 31 | ## setRowHeight 32 | 33 | 34 | ## setTransformScale 35 | 36 | 37 | ## updateWidth 38 | 39 | -------------------------------------------------------------------------------- /vitepress-docs/components/grid-item-events.md: -------------------------------------------------------------------------------- 1 | # GridItem VUE Events 2 | 3 | See https://github.com/gwinnem/vue-responsive-grid-layout/blob/main/src/core/griditem/enums/EGridItemEvents.ts for a list of defined emit events. 4 | And See https://github.com/gwinnem/vue-responsive-grid-layout/blob/main/src/components/Grid/GridItem.vue#L108-L117 for updated event definitions 5 | 6 | ## container-resized 7 | Container Resized event 8 | 9 | Every time the grid item/layout container changes size (browser window or other) 10 | 11 | ```typescript 12 | containerResizedEvent: function(i, newH, newW, newHPx, newWPx): void { 13 | console.log("CONTAINER RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 14 | } 15 | ``` 16 | 17 | 18 | ## drag 19 | 20 | Every time an item is being dragged 21 | 22 | ```typescript 23 | dragEvent: function(i, h, w, height, width): void { 24 | console.log("DRAG i=" + i + ", h=" + h + ", w=" + w + ", height=" + height + ", width=" + width); 25 | } 26 | ``` 27 | 28 | ## dragged 29 | 30 | Every time an item is finished being dragged 31 | 32 | ```typescript 33 | dragEvent: function(i, h, w, height, width): void { 34 | console.log("DRAGGED i=" + i + ", h=" + h + ", w=" + w + ", height=" + height + ", width=" + width); 35 | } 36 | ``` 37 | 38 | ## item-move 39 | Move event 40 | 41 | Every time an item is being moved and changes position 42 | 43 | ```typescript 44 | moveEvent: function(i, newX, newY): void { 45 | console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY); 46 | } 47 | ``` 48 | 49 | ## item-moved 50 | Moved event 51 | 52 | Every time an item is finished being moved and changes position 53 | 54 | ```typescript 55 | movedEvent: function(i, newX, newY): void { 56 | console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY); 57 | } 58 | ``` 59 | 60 | 61 | ## remove-grid-item 62 | Emitted when the user clicks the close button in a `GridItem`. 63 | 64 | ```typescript 65 | const closeClicked = (id: number): void => { 66 | emit(`remove-grid-item`, id); 67 | }; 68 | ``` 69 | 70 | 71 | ## resize 72 | Resize event 73 | 74 | Every time an item is being resized and changes size 75 | 76 | ```typescript 77 | resizeEvent: function(i, newH, newW, newHPx, newWPx): void { 78 | console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 79 | } 80 | ``` 81 | 82 | 83 | ## resized 84 | 85 | Every time an item is finished being resized and changes size 86 | 87 | ```typescript 88 | resizeEvent: function(i, newH, newW, newHPx, newWPx): void { 89 | console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); 90 | } 91 | ``` 92 | 93 | -------------------------------------------------------------------------------- /vitepress-docs/components/grid-item-slots.md: -------------------------------------------------------------------------------- 1 | # GridItem slots 2 | 3 | * __Default slot__. 4 | -------------------------------------------------------------------------------- /vitepress-docs/components/grid-item.md: -------------------------------------------------------------------------------- 1 | # GridItem 2 | -------------------------------------------------------------------------------- /vitepress-docs/components/grid-layout-event-bus-events.md: -------------------------------------------------------------------------------- 1 | # GridLayout eventBus Events 2 | 3 | ## compact 4 | * Emitted during drag after layout is compacted. 5 | * Emitted during resize after layout is compacted. 6 | 7 | 8 | ## dragEvent 9 | * Forwarding `dragEvent` emitted from the `GridItem` component. 10 | 11 | ## resizeEvent 12 | 13 | 14 | ## setBounded 15 | 16 | 17 | ## setColNum 18 | 19 | 20 | ## setDraggable 21 | 22 | 23 | ## setMaxRows 24 | 25 | 26 | ## setResizable 27 | 28 | 29 | ## setRowHeight 30 | 31 | 32 | ## setTransformScale 33 | 34 | 35 | ## updateWidth 36 | -------------------------------------------------------------------------------- /vitepress-docs/components/grid-layout-events.md: -------------------------------------------------------------------------------- 1 | # GridLayout VUE Events 2 | 3 | 4 | ## breakpoint-changed 5 | Emitted when the breakpoint is changed during a recalculation of the GridLayout. 6 | 7 | 8 | ## changed-direction 9 | Emitted when the direction of the layout changes (RTL or LTR). 10 | 11 | 12 | ## container-resized 13 | 14 | 15 | ## dragend 16 | Emitted when a GridItem is finished dragging (GridItem is dropped into the GridLayout) 17 | 18 | 19 | ## dragmove 20 | Emitted when a dragged GridItem is being moved. 21 | 22 | 23 | ## dragstart 24 | Emitted when a GridItem starts to being dragged. 25 | 26 | 27 | ## layout-before-mount 28 | Emitted on the component beforeMount lifecycle hook 29 | 30 | ```typescript 31 | layoutBeforeMountEvent: function(newLayout: Layout): void { 32 | console.log("beforeMount layout: ", newLayout); 33 | } 34 | ``` 35 | 36 | ## layout-created 37 | Emitted on the component created lifecycle hook 38 | 39 | 40 | ```typescript 41 | layoutCreatedEvent: function(newLayout: Layout): void { 42 | console.log("Created layout: ", newLayout); 43 | } 44 | ``` 45 | 46 | ## layout-mounted 47 | Emitted on the component mounted lifecycle hook 48 | 49 | 50 | ```typescript 51 | layoutMountedEvent: function(newLayout: Layout): void { 52 | console.log("Mounted layout: ", newLayout); 53 | } 54 | ``` 55 | 56 | 57 | ## layout-ready 58 | Emitted when all the operations on the mount hook finish 59 | 60 | ```typescript 61 | layoutReadyEvent: function(newLayout: Layout): void { 62 | console.log("Ready layout: ", newLayout); 63 | } 64 | ``` 65 | 66 | 67 | ## recalculate-styles 68 | Emitted into the event bus, maybe get this and others into separate enum. 69 | 70 | 71 | ## layout-update 72 | Emitted every time the GridLayout is being updated. 73 | This will fire everytime the GridLayout is updated, the GridItems are dropped or resized in the GridLayout. 74 | 75 | 76 | ```typescript 77 | layoutUpdatedEvent: function(newLayout: Layout): void { 78 | console.log("Updated layout: ", newLayout); 79 | } 80 | ``` 81 | 82 | 83 | ## layout-updated 84 | Emitted when a GridItem is dropped or finished resizing and the GridLayout is updated. 85 | -------------------------------------------------------------------------------- /vitepress-docs/components/grid-layout.md: -------------------------------------------------------------------------------- 1 | # GridLayout 2 | -------------------------------------------------------------------------------- /vitepress-docs/components/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: true 3 | page: true 4 | title: Features 5 | --- 6 | 7 | # Components 8 | 9 | This plugin is exporting the following components: 10 | 11 | 12 | * `GridLayout`, Defines the main grid layout. 13 | * `GridItem` Defines an item in the layout. 14 | * `CustomCloseButton` Customized close button. 15 | 16 | -------------------------------------------------------------------------------- /vitepress-docs/examples/01-example.md: -------------------------------------------------------------------------------- 1 | # Basic Drag & Resize 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /vitepress-docs/examples/02-example.md: -------------------------------------------------------------------------------- 1 | # Dragging is bound to GridLayout container 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /vitepress-docs/examples/03-example.md: -------------------------------------------------------------------------------- 1 | # Drag, Drop and resize events 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /vitepress-docs/examples/04-example.md: -------------------------------------------------------------------------------- 1 | # Multiple Grid layout's 2 | This is a simplified version of this functionality. 3 |
4 | ***Some refactoring is needed to be able to have it work with different layouts.*** 5 | 6 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /vitepress-docs/examples/05-example.md: -------------------------------------------------------------------------------- 1 | # Drag allow/ignore elements 2 | Ignore drag on certain elements and allow on others. 3 | 4 | Click and drag the black dot on the corner of each GridItem to be able to drag it. 5 |
6 | 7 | The GridItem has the following properties set in order to get this functionality. 8 | ```html 9 | drag-allow-from=".vue-draggable-handle" 10 | drag-ignore-from=".no-drag" 11 | ``` 12 | 13 | Style for the black circle drag handler and overriding the cursor property, so the grab and grabbing cursor is not shown. 14 | ```scss 15 | .vue-draggable-handle { 16 | position: absolute; 17 | width: 20px; 18 | height: 20px; 19 | top: -5px; 20 | left: 5px; 21 | background-origin: content-box; 22 | background-color: black; 23 | box-sizing: border-box; 24 | border-radius: 10px; 25 | cursor: grab; 26 | } 27 | 28 | .vue-grid-item { 29 | &.vue-draggable { 30 | cursor: default !important; 31 | } 32 | 33 | &.vue-draggable-dragging { 34 | cursor: grabbing !important; 35 | } 36 | } 37 | ``` 38 | 39 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /vitepress-docs/examples/06-example.md: -------------------------------------------------------------------------------- 1 | # Mirrored / Right to Left layout. 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /vitepress-docs/examples/07-example.md: -------------------------------------------------------------------------------- 1 | # Responsive layout 2 | 3 | The following breakpoints are applied by default: 4 | 5 | ```typescript 6 | breakpoints: (): IBreakpoints => ({ 7 | xxl: 1600, 8 | xl: 1400, 9 | lg: 1200, 10 | md: 996, 11 | sm: 768, 12 | xs: 480, 13 | xxs: 0, 14 | }) 15 | cols: (): IColumns => ({ 16 | xxl: 12, 17 | xl: 12, 18 | lg: 12, 19 | md: 10, 20 | sm: 6, 21 | xs: 4, 22 | xxs: 2, 23 | }) 24 | ``` 25 | ::: tip 26 | Resize the browser window to see how the Grid is behaving. 27 | ::: 28 | 29 | 30 | 33 | -------------------------------------------------------------------------------- /vitepress-docs/examples/08-example.md: -------------------------------------------------------------------------------- 1 | # Prevent collision 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /vitepress-docs/examples/09-example.md: -------------------------------------------------------------------------------- 1 | # Responsive with predefined layouts. 2 | -------------------------------------------------------------------------------- /vitepress-docs/examples/10-example.md: -------------------------------------------------------------------------------- 1 | # Add / Remove Grid items. 2 | Click on the close button to remove an item. Click on the Add button to an item. 3 | 4 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /vitepress-docs/examples/11-example.md: -------------------------------------------------------------------------------- 1 | # Drag & Drop from outside the grid. 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /vitepress-docs/examples/12-example.md: -------------------------------------------------------------------------------- 1 | # Drag & Drop between Grid layouts. 2 | -------------------------------------------------------------------------------- /vitepress-docs/examples/13-example.md: -------------------------------------------------------------------------------- 1 | # Show Default Close Button 2 | Select the showClosebutton to display the default close button. 3 | Click on the button and the item will be removed from the layout. 4 | 5 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /vitepress-docs/examples/14-example.md: -------------------------------------------------------------------------------- 1 | # Add default border-radius. 2 | The GridItem has a property for adding a 12px border-radius to it. 3 |
4 | Select the useBorderRadius to show it. 5 | 6 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /vitepress-docs/examples/15-example.md: -------------------------------------------------------------------------------- 1 | # Horizontal shift of GridItem's when they are being dragged. 2 |
3 | 4 | When ***horizontalShift*** is not set, the GridItem's will shift vertically. 5 | Set it to ```true``` and they will shift horizontally instead. This applies when you are dragging a GridItem over another horizontally. 6 | 7 |
8 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /vitepress-docs/examples/16-example.md: -------------------------------------------------------------------------------- 1 | # Horizontal shift of GridItem's when they are being dragged. 2 |
3 | 4 | When ***horizontalShift*** is not set, the GridItem's will shift vertically. 5 | Set it to ```true``` and they will shift horizontally instead. This applies when you are dragging a GridItem over another horizontally. 6 | 7 |
8 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /vitepress-docs/examples/components/test.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import type { TLayout } from 'vue-ts-responsive-grid-layout'; 3 | 4 | export const testData: TLayout = [ 5 | { 6 | h: 2, 7 | i: 1, 8 | w: 1, 9 | x: 0, 10 | y: 2, 11 | }, 12 | { 13 | h: 2, 14 | i: 2, 15 | w: 1, 16 | x: 1, 17 | y: 2, 18 | }, 19 | { 20 | h: 2, 21 | i: 3, 22 | w: 1, 23 | x: 2, 24 | y: 2, 25 | }, 26 | { 27 | h: 2, 28 | i: 4, 29 | w: 1, 30 | x: 3, 31 | y: 2, 32 | }, 33 | { 34 | h: 2, 35 | i: 5, 36 | w: 1, 37 | x: 0, 38 | y: 2, 39 | }, 40 | { 41 | h: 2, 42 | i: 6, 43 | w: 1, 44 | x: 1, 45 | y: 2, 46 | }, 47 | { 48 | h: 2, 49 | i: 7, 50 | w: 1, 51 | x: 2, 52 | y: 2, 53 | }, 54 | { 55 | h: 2, 56 | i: 8, 57 | w: 1, 58 | x: 3, 59 | y: 2, 60 | }, 61 | ]; 62 | -------------------------------------------------------------------------------- /vitepress-docs/examples/components/test2.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import type { TLayout } from 'vue-ts-responsive-grid-layout'; 3 | 4 | export const testData2: TLayout = [ 5 | { 6 | h: 2, 7 | i: 1, 8 | w: 1, 9 | x: 0, 10 | y: 0, 11 | }, 12 | { 13 | h: 4, 14 | i: 2, 15 | w: 1, 16 | x: 1, 17 | y: 0, 18 | }, 19 | { 20 | h: 3, 21 | i: 3, 22 | w: 1, 23 | x: 2, 24 | y: 0, 25 | }, 26 | ]; 27 | -------------------------------------------------------------------------------- /vitepress-docs/features/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | page: true 4 | title: Features 5 | --- 6 | 7 | # Features 8 | 9 | * VUE 3 with Typescript. 10 | * Vite used as dev server and bundler. 11 | * Vitepress used for documentation. 12 | * Automatic responsiveness with breakpoints configuration. 13 | * GridItem Border Radius. 14 | * GridLayout Edit Mode. 15 | * Horizontal Shift. 16 | * Close button in GridItem. 17 | * New Test application, styled with [mini.css](https://minicss.us/). 18 | * Cursor styling. 19 | * Fixed mirrored layout so only the GridItems are rearranged. 20 | * Draggable widgets. 21 | * Resizable widgets. 22 | * Static widgets. 23 | * Bounds checking for dragging and resizing. 24 | * Widgets may be added or removed without rebuilding grid. 25 | * Layout can be serialized and restored. 26 | * Responsive with predefined Layouts. 27 | * Grid items are distributed evenly. 28 | * Grid item is resizable from right, bottom right and bottom. 29 | -------------------------------------------------------------------------------- /vitepress-docs/guide/changelog.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | footer: true 4 | page: true 5 | title: Changelog 6 | --- 7 | 8 | ## Changelog 9 | 10 | 11 | ### v: 1.2.10 (2025-04-28) 12 | * __Demo App__ [Eventlog is not displaying any resize events.](https://github.com/gwinnem/vue-responsive-grid-layout/issues/46) 13 | * __Fixed Issue__ [The margin property cannot be [0,0]](https://github.com/gwinnem/vue-responsive-grid-layout/issues/64) 14 | * __Fixed Issue__ [Hide resize cursor change when GridItem is not resizable](https://github.com/gwinnem/vue-responsive-grid-layout/issues/49) 15 | * __Tests__ Added more unit tests and refactored code so it is easier to test. 16 | * __Tests__ Updated vitest.config.js coverage exclude section. 17 | 18 | 19 | ### v: 1.2.9 (2024-02-03) 20 | * __Fixed Issue__ [Dynamic change columns, item will overlap](https://github.com/gwinnem/vue-responsive-grid-layout/issues/12) 21 | 22 | 23 | ### v: 1.2.8 (2024-01-25) 24 | * __Fixed Issue__ [Unexpected Behavior when dragging items](https://github.com/gwinnem/vue-responsive-grid-layout/issues/54) Tnxs to [T0miii](https://github.com/T0miii) 25 | 26 | 27 | ### v: 1.2.7 (2024-01-10) 28 | * __Fixed Issue__ [option "responsive" not working](https://github.com/gwinnem/vue-responsive-grid-layout/issues/51). Tnxs to [T0miii](https://github.com/T0miii) 29 | 30 | 31 | ### v: 1.2.6 (2023-12-28) 32 | * __Fixed Issue__ Problem if layout doesnt have static item [PullRequest](https://github.com/gwinnem/vue-responsive-grid-layout/pull/47) 33 | 34 | 35 | ### v: 1.2.5 (2023-12-14) 36 | * __Fixed Issue__ [editMode not working as expected](https://github.com/gwinnem/vue-responsive-grid-layout/issues/33) 37 | * __Documentation__ Updated config so when refreshing a page it loads the correct page and not the 404 page. 38 | * __Demo App__ Added inputs for Margins. 39 | * __Refactor__ Updated style for gridlines in GridLayout.vue. 40 | * __Config__ Added style linting to project. 41 | * __Config__ Updated scripts section in package.json. 42 | * __Demo App__ Fixed index value when dropping a new GridItem onto the layout. This only works when index is a numeric value. 43 | * __Demo App__ Added checks so number input can not have less than 1. 44 | * __Tests__ Added more unit tests and refactored code so it is easier to test. 45 | 46 | 47 | 48 | ### v: 1.2.4 (2023-10-23) 49 | 50 | * __Fixed Issue__ [Layout update event is raised before update is finished](https://github.com/gwinnem/vue-responsive-grid-layout/issues/19). Tnxs to [SamGeems](https://github.com/SamGeens) 51 | * __Fixed issue__ [Close button css is different from the example](https://github.com/gwinnem/vue-responsive-grid-layout/issues/20). Tnxs to [SamGeems](https://github.com/SamGeens) 52 | * __Feature__ Added event __drag-end__ to GridLayout. 53 | * __Feature__ Added event __drag-move__ to GridLayout. 54 | * __Feature__ Added event __drag-start__ to GridLayout. 55 | * __Codebase__ Renamed EGridLayoutEvent value UPDATE_LAYOUT to LAYOUT_UPDATE. 56 | * __Codebase__ Removed file EDragEvents and updated GridLayout. Values are implemented in EGridLayoutEvent. 57 | * __Codebase__ Added documentation to file DOM.ts 58 | * __Codebase__ Added new enum for drag events and refactored GridLayout to use new enum. 59 | * __Refactor__ Removed obsolete enum EMovingDirections. 60 | * __Demo App__ Added button for clearing the event log. 61 | * __Demo App__ Added Dropdown for filtering on events. 62 | 63 | ### v: 1.2.2 (2023-09-19) 64 | 65 | * __Fixed Issue__ [Drag and Drop from outside is not working when distributeEvenly prop is set](https://github.com/gwinnem/vue-responsive-grid-layout/issues/5) 66 | * __Partial Fix__ [Resizemove edges case handling is incomplete](https://github.com/gwinnem/vue-responsive-grid-layout/issues/13) 67 | * __Right, Right Bottom and Bottom__ resize fixed. 68 | * __Left, Top Left, Top and Top Right__ resize not fixed. 69 | * __Codebase__ Adding description to functions. 70 | * __Codebase__ Added contributors to package.json. 71 | * __Codebase__ Added badges to README file. 72 | * __Codebase__ Fixed outdated dependencies. 73 | 74 | Thanks to [UTing1119](https://github.com/UTing1119) for his contribution to this release. 75 | 76 | ### v: 1.2.1 (2023-05-07) 77 | 78 | * --Fixed Issue-- [Issue 7](https://github.com/gwinnem/vue-responsive-grid-layout/issues/7), thanks to [UTing1119](https://github.com/UTing1119) 79 | * --Fixed Issue-- [Issue 6](https://github.com/gwinnem/vue-responsive-grid-layout/issues/6), thanks to [UTing1119](https://github.com/UTing1119) 80 | -------------------------------------------------------------------------------- /vitepress-docs/guide/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | page: true 3 | title: Installation 4 | --- 5 | 6 | # Installation 7 | 8 | ## NPM 9 | ``` 10 | npm install vue-ts-responsive-grid-layout --save 11 | ``` 12 | 13 | ## Yarn 14 | ``` 15 | yarn add vue-ts-responsive-grid-layout 16 | ``` 17 | 18 | ## Import the package 19 | 20 | ```typescript 21 | import VueResponsiveGridLayout from 'vue-ts-responsive-grid-layout'; 22 | ``` 23 | 24 | Add to other Vue components using Options api. 25 | 26 | ```typescript 27 | export default { 28 | components: { 29 | GridLayout: VueResponsiveGridLayout.GridLayout, 30 | GridItem: VueResponsiveGridLayout.GridItem 31 | }, 32 | // ... data, methods, mounted (), etc. 33 | } 34 | ``` 35 | 36 | Add to other Vue components using Composition api. 37 | 38 | ```html 39 | 42 | ``` 43 | -------------------------------------------------------------------------------- /vitepress-docs/guide/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | footer: true 4 | page: true 5 | title: Introduction 6 | --- 7 | 8 | 9 | # What is vue-ts-responsive-grid-layout? 10 | A responsive grid layout component for creating advance dashboard's. 11 | -------------------------------------------------------------------------------- /vitepress-docs/guide/roadmap.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | footer: true 4 | page: true 5 | title: Roadmap 6 | --- 7 | 8 | # ROADMAP 9 | 10 | ## Upcoming updates and fixes 11 | * __New Feature__ Implement resize from left side. 12 | * __New Feature__ Implement resize from top-left side. 13 | * __New Feature__ Implement resize from bottom-left side. 14 | * __New Feature__ Drag & Drop from Multiple Grids. 15 | * __New Feature__ Add native drag and drop to GridLayout. 16 | * __New Feature__ Add possibility to set fixed width on a GridItem. 17 | * __New Feature__ Add pre styled GridItem. 18 | * __New Feature__ Implement RTL resize. 19 | * __New Feature__ Support for nuxt projects. 20 | * __Examples__ Dynamic add new GridItems. 21 | * __Examples__ Add example app to CodeSandbox, so user's can test layouts. 22 | * __Examples__ Add Multiple Grids. 23 | * __Examples__ Add Responsive predefined layouts. 24 | * __Examples__ Drag, drop from grid to grid. 25 | * __Test__ Add e2e tests. 26 | * __Test__ Continuously refactoring and adding new unit tests. 27 | -------------------------------------------------------------------------------- /vitepress-docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: Vue 3 Responsive Grid Layout. 5 | titleTemplate: Main 6 | 7 | hero: 8 | name: Vue 3 Responsive Grid Layout. 9 | tagline: Draggable, Resizeable widgets. 10 | image: 11 | src: /Data Grid.svg 12 | alt: logo 13 | actions: 14 | - theme: brand 15 | text: Get Started 16 | link: /guide/introduction 17 | 18 | features: 19 | - icon: ⚡️ 20 | title: Latest Release version 21 | details: 1.2.10 Released 2025-04-28. 22 | - icon: 💥 23 | title: Responsive Grid Layouts 24 | details: With predefined layout's or automatically with predefined breakpoints. 25 | - icon: 🔱 26 | title: Draggable GridItems 27 | details: Examples showing howto Drag and Drop a GridItem. 28 | - icon: 🔱 29 | title: Resizeable GridItems 30 | details: Constantly being updated for each release.. 31 | --- 32 | -------------------------------------------------------------------------------- /vitepress-docs/public/Data Grid.svg: -------------------------------------------------------------------------------- 1 | 2 | Icons8 RSL Colored Part 10 3 | -------------------------------------------------------------------------------- /vitepress-docs/public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /vitepress-docs/public/npm-square-red.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vitest.config.js: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import { defineConfig } from 'vitest/config'; 3 | import vue from '@vitejs/plugin-vue'; 4 | 5 | export default defineConfig({ 6 | plugins: [vue()], 7 | resolve: { 8 | alias: { 9 | '@': path.resolve(__dirname, `./src`), 10 | }, 11 | }, 12 | test: { 13 | environment: `jsdom`, 14 | globals: true, 15 | include: [`tests/*.spec.ts`, `tests/unit/*.spec.ts`], 16 | coverage: { 17 | enabled: true, 18 | provider: 'v8', 19 | reporter: ['text', 'json', 'html'], 20 | reportsDirectory: './tests/coverage', 21 | exclude: [ 22 | './sandbox', 23 | './vitepress-docs', 24 | './docs', 25 | './dist', 26 | './tests', 27 | './vite.config.js', 28 | './vitest.config.js', 29 | './.*', 30 | './env.d.ts', 31 | './changelog.config.js', 32 | './src/vite-env.d.ts', 33 | './src/core/helpers/DOM.ts', 34 | './src/core/common/interfaces', 35 | './src/core/common/types', 36 | './src/core/common/enums', 37 | './src/core/griditem/enums', 38 | './src/core/griditem/interfaces', 39 | './src/core/gridlayout/enums', 40 | './src/core/gridlayout/interfaces', 41 | './src/hooks', 42 | './src/components/common', 43 | './src/components/index.ts', 44 | './src/components/Grid' 45 | ], 46 | }, 47 | }, 48 | }); 49 | --------------------------------------------------------------------------------