diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a5211b2..01d8df74 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,18 @@ # Contributing Guide -1. Make sure you put things in the right category! -2. Always add your items to the end of a list. To be fair, the order is first-come-first-serve. -3. If you think something belongs in the wrong category, or think there needs to be a new category, feel free to edit things too. +To add another awesome resource, simply create a `.md` file under an appropriate directory in `/awesomeness` with these contents: + +``` yaml +--- +name: Your Project Name +url: http://yourproject.io +author: "Your Name (http://yourhomepage.net)" +description: "[Markdown](https://daringfireball.net/projects/markdown/) is supported!" +tags: + - pure + - awesomess +``` + +The only mandatory information is `name`, though obviously, you're encouraged to fill in as much information as you can! + +Note: Since the `.md` file actually uses YAML syntax and is parsed by a YAML parser, you'll need quotes if your content includes special characters, e.g. `:`, `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `\`. Or, to play it safe, just quote all the things™! diff --git a/README.md b/README.md index d36c2e20..65117954 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,16 @@ # awesome-vue -> A curated list of awesome things related to Vue.js +A curated list of awesome things related to Vue.js. Inspired by [HTML5 Please](https://github.com/h5bp/html5please/). See the site in action [here](https://awesome.vuejs.org). ## Build Setup -``` bash -# install dependencies -npm install +Here you go: -# serve with hot reload at localhost:8080 -npm run dev +* `npm install` to install dependencies +* `npm run dev` to serve the dev version with hot reload at localhost:8080 +* `npm run build` to build for production with minification +* `npm run parse` to parse the awesome resources into a JSON data file -# build for production with minification -npm run build -``` +## License -For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader). +MIT diff --git a/app/site/index.html b/app/site/index.html index 754fe84a..2603c17c 100644 --- a/app/site/index.html +++ b/app/site/index.html @@ -4,6 +4,7 @@ Awesome Vue + diff --git a/app/site/src/App.vue b/app/site/src/App.vue index 7d762b32..882774e5 100644 --- a/app/site/src/App.vue +++ b/app/site/src/App.vue @@ -2,17 +2,14 @@
-
-

Awesome Vue.js

-

A curated list of awesome things related to - Vue.js

-
+
@@ -48,9 +38,11 @@ import _ from 'lodash' import { event } from './utils' import group from './components/Group.vue' import explore from './components/Explore.vue' +import mainHeader from './components/Header.vue' +import mainFooter from './components/Footer.vue' export default { - components: { group, explore }, + components: { group, explore, mainHeader, mainFooter }, data () { return { @@ -59,8 +51,35 @@ export default { } }, - watch: { - q() { + created() { + // Listen to the 'tag-selected' event to trigger the filtering process. + event.on('tag-selected', tag => { + this.q = tag[0] + + // Set the focus into the search field. Some little UX doesn't kill. + this.$nextTick(() => { + document.getElementById('seachField').focus() + }) + + this.debounceFilter() + }) + + // Also, upon page load, tf there's a hash, we filter the awesome list + // right away. + if (window.location.hash) { + this.q = /^#(.*)/.exec(window.location.hash)[1].toLowerCase() + this.debounceFilter() + } + }, + + methods: { + /** + * Limit filtering using lodash's debounce. + * @param {Event} + * @param {VueComponent} + * @return {Function} + */ + debounceFilter: _.debounce(function () { let q = this.q.trim() if (q === 'everything') { @@ -73,25 +92,8 @@ export default { } this.groups = this.filter(_.cloneDeep(window.data), q) - } - }, + }, 100), - created() { - event.on('tag-selected', tag => { - this.q = tag[0] - - // Set the focus into the search field. Some little UX doesn't kill. - this.$nextTick(() => { - document.getElementById('seachField').focus() - }) - }) - - if (window.location.hash) { - this.q = /^#(.*)/.exec(window.location.hash)[1].toLowerCase() - } - }, - - methods: { /** * Filter our awesome data. * @param {Array.} groups The groups to apply filtering on @@ -216,18 +218,6 @@ code { justify-content: flex-end; background: #fcfcfc; - hgroup { - h1 { - font-size: 2.7rem; - margin-bottom: 1.6rem; - } - - h2 { - font-size: 1.3rem; - margin-bottom: 2.4rem; - } - } - form { margin-bottom: 1.2rem; @@ -310,31 +300,49 @@ code { } } -footer { - margin-top: 4rem; - - .github { - color: #34495e; - font-size: 2rem; - width: 149px; - display: inline-block; - position: relative; - - &::after { - content: ""; - display: block; - width: 100%; - height: 27px; - background: url(./assets/look-here.png) no-repeat; - background-size: 149px; - position: absolute; - right: -5px; - transform: rotate(-4deg); - transform-origin: 100% 0; +@media only screen and (max-width: 1023px) { + #app { + .left, .right { + padding: 24px 16px; } - &:hover::after { - animation: soho 1s ease-in-out infinite; + .right { + overflow-y: scroll; + -webkit-overflow-scrolling: touch; + } + } +} + +@media only screen and (max-width: 735px) { + #app { + display: block; + overflow: auto; + + .left, .right { + width: 100%; + display: block; + } + + .left { + text-align: left; + border-right: 0; + border-bottom: 1px solid #ebebeb; + + form { + label { + display: block; + } + + input[type="search"] { + width: 100%; + } + } + } + + .right { + .wrap { + max-width: 100%; + } } } } diff --git a/app/site/src/components/Explore.vue b/app/site/src/components/Explore.vue index 0e27fa4b..57feda6e 100644 --- a/app/site/src/components/Explore.vue +++ b/app/site/src/components/Explore.vue @@ -3,8 +3,7 @@

Explore

@@ -58,5 +57,20 @@ export default { display: none; } } + + @media only screen and (max-width: 1023px) { + h1 { + display: inline; + font-size: 1rem; + + &::after { + content: ":"; + } + } + + ul { + display: inline; + } + } } diff --git a/app/site/src/components/Footer.vue b/app/site/src/components/Footer.vue new file mode 100644 index 00000000..5e3fe13a --- /dev/null +++ b/app/site/src/components/Footer.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/app/site/src/components/Header.vue b/app/site/src/components/Header.vue new file mode 100644 index 00000000..e9c7358c --- /dev/null +++ b/app/site/src/components/Header.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/app/site/src/components/Item.vue b/app/site/src/components/Item.vue index 2cc7f296..b7aa7fa3 100644 --- a/app/site/src/components/Item.vue +++ b/app/site/src/components/Item.vue @@ -29,14 +29,16 @@ export default { props: ['item'], mixins: [filterByTag], computed: { + /** + * Get a shields.io badge URL for a GitHub repository. + * @return {String|null} + */ githubBadgeUrl() { - const re = /https?:\/\/github\.com\/([A-Za-z0-9-_]*)\/([A-Za-z0-9-_]*)\/?$/i + const re = /https?:\/\/github\.com\/([A-Za-z0-9-_\.]*)\/([A-Za-z0-9-_\.]*)\/?$/i const matches = re.exec(this.item.url) - if (!matches) { - return null - } - - return `https://img.shields.io/github/stars/${matches[1]}/${matches[2]}.svg?style=social&label=★` + return matches + ? `https://img.shields.io/github/stars/${matches[1]}/${matches[2]}.svg?style=social&label=★` + : null } } } diff --git a/package.json b/package.json index 9eae660f..f639f2d3 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "babel-loader": "^6.0.0", "babel-preset-es2015": "^6.0.0", "chalk": "^1.1.3", + "copy-webpack-plugin": "^3.0.1", "cross-env": "^1.0.6", "css-loader": "^0.23.1", "file-loader": "^0.8.4", diff --git a/webpack.config.js b/webpack.config.js index c5f14011..897a9adb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,6 @@ var path = require('path') var webpack = require('webpack') +var cp = require('copy-webpack-plugin') module.exports = { entry: './app/site/src/main.js', @@ -35,7 +36,16 @@ module.exports = { historyApiFallback: true, noInfo: true }, - devtool: '#eval-source-map' + devtool: '#eval-source-map', + plugins: [ + new cp([ + { + context: path.join(__dirname, 'app/site/src/assets'), + from: 'logo.png', + to: path.join(__dirname, 'app/site/dist'), + } + ]) + ] } if (process.env.NODE_ENV === 'production') {