Repository: fuxingloh/vue-masonry-wall
Branch: master
Commit: a02d49c78cfd
Files: 21
Total size: 24.4 KB
Directory structure:
gitextract_pvs8vdpn/
├── .browserslistrc
├── .github/
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── auto_assign.yml
│ ├── pr-labeler.yml
│ ├── release-drafter.yml
│ └── workflows/
│ ├── ci.yml
│ ├── publish.yml
│ ├── release-drafter.yml
│ └── triage.yml
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── babel.config.js
├── build/
│ └── rollup.config.js
├── examples/
│ ├── index.vue
│ ├── package.json
│ └── serve.js
├── package.json
└── src/
├── entry.js
└── vue-masonry-wall.vue
================================================
FILE CONTENTS
================================================
================================================
FILE: .browserslistrc
================================================
current node
last 2 versions and > 2%
ie > 10
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
================================================
FILE: .github/auto_assign.yml
================================================
addAssignees: author
addReviewers: true
reviewers:
- fuxingloh
numberOfReviewers: 0
================================================
FILE: .github/pr-labeler.yml
================================================
feature: [ 'feature/*', 'feat/*', 'enhancement/*' ]
fix: [ 'fix/*', 'bug/*', 'bugfix/*' ]
chore: [ 'chore/*', 'docs/*' , 'doc/*', 'ci/*' ]
================================================
FILE: .github/release-drafter.yml
================================================
name-template: 'v$RESOLVED_VERSION 🌈'
tag-template: 'v$RESOLVED_VERSION'
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 Maintenance'
labels:
- 'chore'
- 'docs'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&'
version-resolver:
minor:
labels:
- 'feature'
- 'enhancement'
patch:
labels:
- 'patch'
- 'bug'
- 'bugfix'
- 'fix'
default: patch
template: |
## Changes
$CHANGES
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
pull_request:
branches: [ master ]
jobs:
yarn:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '14'
registry-url: 'https://registry.npmjs.org'
- run: yarn install --frozen-lockfile
- run: yarn build
================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish
on:
release:
types: [ published ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '14'
registry-url: 'https://registry.npmjs.org'
- run: yarn install --frozen-lockfile
- name: Check package version
uses: technote-space/package-version-check-action@v1
with:
COMMIT_MESSAGE: 'release: update package version'
- run: yarn build
- run: yarn publish --non-interactive
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
================================================
FILE: .github/workflows/release-drafter.yml
================================================
name: Release Drafter
on:
push:
branches: [ master ]
jobs:
draft-release:
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/triage.yml
================================================
name: "Triage"
on:
pull_request:
types: [ opened, reopened, ready_for_review ]
branches: [ master ]
jobs:
triage:
name: Triage
runs-on: ubuntu-latest
steps:
- uses: TimonVS/pr-labeler-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: kentaro-m/auto-assign-action@v1.1.2
================================================
FILE: .gitignore
================================================
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
================================================
FILE: .npmignore
================================================
*
!dist/*
!src/vue-masonry-wall.vue
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Fuxing Loh
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# vue-masonry-wall
A pure vue responsive masonry implementation without direct dom manipulation, ssr friendly with lazy appending.
I created this because other libraries has no SSR support, and I needed a pure vue implementation.
* [Live Demo: Image](https://nuxt-app.now.sh/vue-masonry-wall-image) and the [Source](https://github.com/fuxingloh/nuxt-app/blob/0725466dcf2d3d5338573ca7612f38ecd8fa2fa0/components/examples/ExampleMasonryImage.vue)
* [Live Demo: Text](https://nuxt-app.now.sh/vue-masonry-wall) and the [Source](https://github.com/fuxingloh/nuxt-app/blob/0725466dcf2d3d5338573ca7612f38ecd8fa2fa0/components/examples/ExampleMasonry.vue)
[](https://nuxt-app.now.sh/vue-masonry-wall-image)
## Installation
```shell script
npm i vue-masonry-wall
# or yarn
yarn add vue-masonry-wall
```
## Features
* No Direct DOM Manipulation
* SSR friendly, able to load and re hydrate later
* 1 dependency only, no legacy dependencies
* Auto lazy appending, scroll to auto load more
* Auto item placement, will find best column
* Responsive design
## Usage
```vue
```
```js
const items = []
const options = {
width: 300,
padding: {
default: 12,
1: 6,
2: 8
}
}
const append = () => {
// API call and add items
this.items.push(...[])
}
```
### Basic
```vue
Masonry: append endlessly
{{item.title}}
{{item.content}}
```
### Nuxt SSR
Add `:ssr="{columns: 2}"` to masonry so that during SSR, it will be load in 2 columns.
SSR has no clue what is the size of your height of your element or width of the browser.
You can however guess based on user-agent: https://github.com/nuxt-community/device-module
This param allow you to preload a config for SSR rendering, it will distribute your items into all columns evenly.
```vue
{{item.title}}
{{item.content}}
```
## Dependencies
- [vue-observe-visibility](https://github.com/Akryum/vue-observe-visibility) for [IntersectionObserver](https://github.com/w3c/IntersectionObserver/tree/master/polyfill)
## Contributing
For any question or feature request please feel free to create an [issue](https://github.com/fuxingloh/vue-masonry-wall/issues/new) or [pull request](https://github.com/fuxingloh/vue-masonry-wall/pulls).
## TODO
> These were features from my original project that I removed for brevity of this package.
* [ ] [nuxt-community/device-module](https://github.com/nuxt-community/device-module) to detect the browser for better SSR support.
* [ ] [vue-scrollto](https://www.npmjs.com/package/vue-scrollto) to scroll to an item in masonry.
## [Vue Horizontal](https://github.com/fuxingloh/vue-horizontal)
I also maintain another project called [Vue Horizontal](https://github.com/fuxingloh/vue-horizontal).
At its core, Vue Horizontal is an ultra simple pure vue horizontal layout for
modern responsive web with zero dependencies.
Vue Horizontal is also an ultra complex code snippet dossier with over 100 SPA/SSR/SSG friendly recipes for your design needs.
Do check it out, might be useful for you!
================================================
FILE: babel.config.js
================================================
const devPresets = ['@vue/babel-preset-app'];
const buildPresets = ['@babel/preset-env'];
module.exports = {
presets: (process.env.NODE_ENV === 'development' ? devPresets : buildPresets),
};
================================================
FILE: build/rollup.config.js
================================================
// rollup.config.js
import fs from 'fs';
import path from 'path';
import vue from 'rollup-plugin-vue';
import alias from '@rollup/plugin-alias';
import commonjs from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';
import minimist from 'minimist';
// Get browserslist config and remove ie from es build targets
const esbrowserslist = fs.readFileSync('./.browserslistrc')
.toString()
.split('\n')
.filter((entry) => entry && entry.substring(0, 2) !== 'ie');
const argv = minimist(process.argv.slice(2));
const projectRoot = path.resolve(__dirname, '..');
const baseConfig = {
input: 'src/entry.js',
plugins: {
preVue: [
alias({
resolve: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
entries: {
'@': path.resolve(projectRoot, 'src'),
},
}),
],
replace: {
'process.env.NODE_ENV': JSON.stringify('production'),
'process.env.ES_BUILD': JSON.stringify('false'),
},
vue: {
css: true,
template: {
isProduction: true,
},
},
babel: {
exclude: 'node_modules/**',
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
},
},
};
// ESM/UMD/IIFE shared settings: externals
// Refer to https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
const external = [
// list external dependencies, exactly the way it is written in the import statement.
// eg. 'jquery'
'vue',
];
// UMD/IIFE shared settings: output.globals
// Refer to https://rollupjs.org/guide/en#output-globals for details
const globals = {
// Provide global variable names to replace your external imports
// eg. jquery: '$'
vue: 'Vue',
};
// Customize configs for individual targets
const buildFormats = [];
if (!argv.format || argv.format === 'es') {
const esConfig = {
...baseConfig,
external,
output: {
file: 'dist/vue-masonry-wall.esm.js',
format: 'esm',
exports: 'named',
},
plugins: [
replace({
...baseConfig.plugins.replace,
'process.env.ES_BUILD': JSON.stringify('true'),
}),
...baseConfig.plugins.preVue,
vue(baseConfig.plugins.vue),
babel({
...baseConfig.plugins.babel,
presets: [
[
'@babel/preset-env',
{
targets: esbrowserslist,
},
],
],
}),
commonjs(),
],
};
buildFormats.push(esConfig);
}
if (!argv.format || argv.format === 'cjs') {
const umdConfig = {
...baseConfig,
external,
output: {
compact: true,
file: 'dist/vue-masonry-wall.ssr.js',
format: 'cjs',
name: 'VueMasonryWall',
exports: 'named',
globals,
},
plugins: [
replace(baseConfig.plugins.replace),
...baseConfig.plugins.preVue,
vue({
...baseConfig.plugins.vue,
template: {
...baseConfig.plugins.vue.template,
optimizeSSR: true,
},
}),
babel(baseConfig.plugins.babel),
commonjs(),
],
};
buildFormats.push(umdConfig);
}
if (!argv.format || argv.format === 'iife') {
const unpkgConfig = {
...baseConfig,
external,
output: {
compact: true,
file: 'dist/vue-masonry-wall.min.js',
format: 'iife',
name: 'VueMasonryWall',
exports: 'named',
globals,
},
plugins: [
replace(baseConfig.plugins.replace),
...baseConfig.plugins.preVue,
vue(baseConfig.plugins.vue),
babel(baseConfig.plugins.babel),
commonjs(),
terser({
output: {
ecma: 5,
},
}),
],
};
buildFormats.push(unpkgConfig);
}
// Export config
export default buildFormats;
================================================
FILE: examples/index.vue
================================================
Masonry: append 100
{{ item.title }}
{{ item.content }}
================================================
FILE: examples/package.json
================================================
{
"name": "abc",
"version": "1.0.0",
"description": "",
"main": "dist/abc.ssr.js",
"browser": "dist/abc.esm.js",
"module": "dist/abc.esm.js",
"unpkg": "dist/abc.min.js",
"files": [
"dist/*",
"src/**/*.vue"
],
"scripts": {
"serve": "vue-cli-service serve dev/serve.js",
"build": "cross-env NODE_ENV=production rollup --config build/rollup.config.js",
"build:ssr": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format cjs",
"build:es": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format es",
"build:unpkg": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format iife"
},
"dependencies": {
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@rollup/plugin-alias": "^2.2.0",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-replace": "^2.3.2",
"@vue/cli-plugin-babel": "^4.3.1",
"@vue/cli-service": "^4.3.1",
"cross-env": "^7.0.2",
"minimist": "^1.2.5",
"rollup": "^2.7.3",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-vue": "^5.1.6",
"vue": "^2.6.11",
"vue-template-compiler": "^2.6.11"
},
"peerDependencies": {
"vue": "^2.6.11"
},
"engines": {
"node": ">=10"
}
}
================================================
FILE: examples/serve.js
================================================
import Vue from "vue";
import Index from "./index.vue";
Vue.config.productionTip = false;
new Vue({
render: (h) => h(Index),
}).$mount("#app");
================================================
FILE: package.json
================================================
{
"name": "vue-masonry-wall",
"version": "0.2.5",
"description": "100% vue masonry without direct dom manipulation, ssr friendly.",
"author": "Fuxing Loh",
"repository": {
"type": "git",
"url": "https://github.com/fuxingloh/vue-masonry-wall.git"
},
"bugs": "https://github.com/fuxingloh/vue-masonry-wall/issues",
"keywords": [
"vue",
"vuejs",
"masonry",
"pinterest"
],
"license": "MIT",
"private": false,
"main": "dist/vue-masonry-wall.ssr.js",
"browser": "dist/vue-masonry-wall.esm.js",
"module": "dist/vue-masonry-wall.esm.js",
"unpkg": "dist/vue-masonry-wall.min.js",
"files": [
"dist/*",
"src/**/*.vue"
],
"scripts": {
"build": "cross-env NODE_ENV=production rollup --config build/rollup.config.js",
"build:ssr": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format cjs",
"build:es": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format es",
"build:unpkg": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format iife",
"examples:serve": "vue-cli-service serve examples/serve.js",
"examples:build": "vue-cli-service build examples/serve.js",
"prepublishOnly": "yarn build"
},
"dependencies": {
"vue-observe-visibility": "^0.4.6"
},
"peerDependencies": {
"lodash": "^4.17.15",
"vue": "^2.6.10"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@rollup/plugin-alias": "^2.2.0",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-replace": "^2.3.2",
"@vue/cli-plugin-babel": "^4.3.1",
"@vue/cli-service": "^4.3.1",
"cross-env": "^7.0.2",
"minimist": "^1.2.5",
"rollup": "^2.7.3",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-vue": "^5.1.6",
"vue": "^2.6.11",
"vue-template-compiler": "^2.6.11"
},
"engines": {
"node": ">=10"
}
}
================================================
FILE: src/entry.js
================================================
// Import vue component
import component from '@/vue-masonry-wall.vue';
// install function executed by Vue.use()
const install = function installVueMasonryWall(Vue) {
if (install.installed) return;
install.installed = true;
Vue.component('VueMasonryWall', component);
};
// Create module definition for Vue.use()
const plugin = {
install,
};
// To auto-install on non-es builds, when vue is found
// eslint-disable-next-line no-redeclare
/* global window, global */
if ("false" === process.env.ES_BUILD) {
let GlobalVue = null;
if (typeof window !== "undefined") {
GlobalVue = window.Vue;
} else if (typeof global !== "undefined") {
GlobalVue = global.Vue;
}
if (GlobalVue) {
GlobalVue.use(plugin);
}
}
// Inject install function into component - allows component
// to be registered via Vue.use() as well as Vue.component()
component.install = install;
// Export component by default
export default component;
// It's possible to expose named exports when writing components that can
// also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo';
// export const RollupDemoDirective = component;
================================================
FILE: src/vue-masonry-wall.vue
================================================