├── .babelrc ├── server ├── server.js ├── posts │ ├── 2015-11-23__what-is-grommet │ │ ├── images │ │ │ └── cover.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2015-11-24__welcome-to-our-blog │ │ ├── images │ │ │ └── cover.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-02-04__why-we-chose-react │ │ ├── images │ │ │ └── react_blog_image.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-04-28__grommet-062-released │ │ ├── images │ │ │ └── new-version-release.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2015-12-10__how-to-contribute-to-grommet-on-github │ │ ├── images │ │ │ ├── fork.png │ │ │ ├── laptop_code1.jpg │ │ │ └── compare_and_pr.png │ │ ├── metadata.json │ │ └── content.md │ ├── 2015-11-30__discover-grommet-at-hpe-discover-2015-in-london │ │ ├── images │ │ │ ├── cover.jpg │ │ │ └── buttons-225x300.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-03-10__the-great-grommet-podcast-episode-two │ │ ├── images │ │ │ └── podcast-blog-art.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-03-22__the-great-grommet-podcast-episode-three │ │ ├── images │ │ │ └── podcast-blog-art.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2015-12-28__2016-responsive-design-trends-with-ethan-marcotte │ │ ├── images │ │ │ └── option_4.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-02-12__why-you-should-be-friends-with-your-style-guide │ │ ├── images │ │ │ └── blog_image.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london │ │ ├── images │ │ │ ├── london.jpg │ │ │ ├── IMG_1228.jpg │ │ │ └── IMG_1218-225x300.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-06-09__interview-with-lee-byron-react-developer-at-facebook │ │ ├── images │ │ │ ├── leebyron.jpg │ │ │ └── Grommet_React_original.png │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-02-10__welcome-to-the-first-ever-great-grommet-podcast │ │ ├── images │ │ │ └── podcast-blog-art.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-07-06__grommet-course-3-accessibility-and-internationalization │ │ ├── images │ │ │ └── screenshot.png │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-03-31__grommet-training-series-part-1-getting-started-with-grommet │ │ ├── images │ │ │ └── option1.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-04-08__top-5-rules-for-giving-enterprise-apps-a-consumer-grade-ux │ │ ├── images │ │ │ └── 5character.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-09-01__how-we-landed-on-jest-snapshot-testing-for-javascript │ │ ├── images │ │ │ └── HP20141219607.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2015-12-23__hacking-lunchtime-the-usdas-eat-school-lunch-ux-challenge │ │ ├── images │ │ │ └── screenshot-4-1200x675.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-03-21__designing-in-a-large-enterprise-company-part-1-design-a-very-overused-term │ │ ├── images │ │ │ └── grommet-blog-1200x670.jpg │ │ ├── metadata.json │ │ └── content.md │ ├── 2016-04-18__the-great-grommet-podcast-episode-four-an-interview-with-digital-accessibility-pro-jennison-asuncion │ │ ├── images │ │ │ └── podcast-blog-art.jpg │ │ ├── metadata.json │ │ └── content.md │ └── 2016-08-10__css-in-js-may-not-be-the-solution-to-all-your-problems │ │ └── metadata.json ├── views │ └── index.ejs ├── utils │ └── post.js ├── blog.js ├── post.js └── persistance │ └── PostDAO.js ├── src ├── js │ ├── Blog.js │ ├── components │ │ ├── Loading.js │ │ ├── social │ │ │ ├── SocialShare.js │ │ │ ├── RedditShare.js │ │ │ ├── TwitterShare.js │ │ │ ├── LinkedinShare.js │ │ │ └── FacebookShare.js │ │ ├── Error.js │ │ ├── manage │ │ │ ├── PreviewPost.js │ │ │ ├── ManageDeletePost.js │ │ │ ├── ManageCancelChangePost.js │ │ │ ├── ManageAddPost.js │ │ │ ├── Header.js │ │ │ ├── ManageEditPost.js │ │ │ ├── ImageForm.js │ │ │ └── Manage.js │ │ ├── NotFound.js │ │ ├── Header.js │ │ ├── Footer.js │ │ ├── Post.js │ │ ├── Archive.js │ │ ├── Search.js │ │ └── PostBody.js │ ├── utils │ │ └── blog.js │ ├── BlogContext.js │ ├── index.js │ ├── routes.js │ ├── RouteHistory.js │ ├── Home.js │ └── store.js ├── scss │ ├── index.scss │ └── highlight-js.github.scss └── index.html ├── .gitignore ├── README.md ├── grommet-toolbox.config.js ├── .travis.yml ├── package.json ├── .eslintrc ├── gulpfile.babel.js ├── .scss-lint.yml └── LICENSE /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ "es2015", "react" ], 3 | "plugins": [ 4 | "transform-object-rest-spread", 5 | "array-includes" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | require('babel-register'); 4 | require('./blog'); 5 | -------------------------------------------------------------------------------- /server/posts/2015-11-23__what-is-grommet/images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-11-23__what-is-grommet/images/cover.jpg -------------------------------------------------------------------------------- /server/posts/2015-11-24__welcome-to-our-blog/images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-11-24__welcome-to-our-blog/images/cover.jpg -------------------------------------------------------------------------------- /server/posts/2016-02-04__why-we-chose-react/images/react_blog_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-02-04__why-we-chose-react/images/react_blog_image.jpg -------------------------------------------------------------------------------- /server/posts/2016-04-28__grommet-062-released/images/new-version-release.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-04-28__grommet-062-released/images/new-version-release.jpg -------------------------------------------------------------------------------- /server/posts/2015-12-10__how-to-contribute-to-grommet-on-github/images/fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-12-10__how-to-contribute-to-grommet-on-github/images/fork.png -------------------------------------------------------------------------------- /server/posts/2015-12-10__how-to-contribute-to-grommet-on-github/images/laptop_code1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-12-10__how-to-contribute-to-grommet-on-github/images/laptop_code1.jpg -------------------------------------------------------------------------------- /server/posts/2015-11-30__discover-grommet-at-hpe-discover-2015-in-london/images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-11-30__discover-grommet-at-hpe-discover-2015-in-london/images/cover.jpg -------------------------------------------------------------------------------- /server/posts/2015-12-10__how-to-contribute-to-grommet-on-github/images/compare_and_pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-12-10__how-to-contribute-to-grommet-on-github/images/compare_and_pr.png -------------------------------------------------------------------------------- /server/posts/2016-03-10__the-great-grommet-podcast-episode-two/images/podcast-blog-art.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-03-10__the-great-grommet-podcast-episode-two/images/podcast-blog-art.jpg -------------------------------------------------------------------------------- /server/posts/2016-03-22__the-great-grommet-podcast-episode-three/images/podcast-blog-art.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-03-22__the-great-grommet-podcast-episode-three/images/podcast-blog-art.jpg -------------------------------------------------------------------------------- /server/posts/2015-12-28__2016-responsive-design-trends-with-ethan-marcotte/images/option_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-12-28__2016-responsive-design-trends-with-ethan-marcotte/images/option_4.jpg -------------------------------------------------------------------------------- /server/posts/2016-02-12__why-you-should-be-friends-with-your-style-guide/images/blog_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-02-12__why-you-should-be-friends-with-your-style-guide/images/blog_image.jpg -------------------------------------------------------------------------------- /server/posts/2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london/images/london.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london/images/london.jpg -------------------------------------------------------------------------------- /server/posts/2016-06-09__interview-with-lee-byron-react-developer-at-facebook/images/leebyron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-06-09__interview-with-lee-byron-react-developer-at-facebook/images/leebyron.jpg -------------------------------------------------------------------------------- /server/posts/2015-11-30__discover-grommet-at-hpe-discover-2015-in-london/images/buttons-225x300.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-11-30__discover-grommet-at-hpe-discover-2015-in-london/images/buttons-225x300.jpg -------------------------------------------------------------------------------- /server/posts/2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london/images/IMG_1228.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london/images/IMG_1228.jpg -------------------------------------------------------------------------------- /server/posts/2016-02-10__welcome-to-the-first-ever-great-grommet-podcast/images/podcast-blog-art.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-02-10__welcome-to-the-first-ever-great-grommet-podcast/images/podcast-blog-art.jpg -------------------------------------------------------------------------------- /server/posts/2016-07-06__grommet-course-3-accessibility-and-internationalization/images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-07-06__grommet-course-3-accessibility-and-internationalization/images/screenshot.png -------------------------------------------------------------------------------- /server/posts/2016-03-31__grommet-training-series-part-1-getting-started-with-grommet/images/option1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-03-31__grommet-training-series-part-1-getting-started-with-grommet/images/option1.jpg -------------------------------------------------------------------------------- /server/posts/2016-04-08__top-5-rules-for-giving-enterprise-apps-a-consumer-grade-ux/images/5character.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-04-08__top-5-rules-for-giving-enterprise-apps-a-consumer-grade-ux/images/5character.jpg -------------------------------------------------------------------------------- /server/posts/2016-09-01__how-we-landed-on-jest-snapshot-testing-for-javascript/images/HP20141219607.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-09-01__how-we-landed-on-jest-snapshot-testing-for-javascript/images/HP20141219607.jpg -------------------------------------------------------------------------------- /server/posts/2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london/images/IMG_1218-225x300.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london/images/IMG_1218-225x300.jpg -------------------------------------------------------------------------------- /server/posts/2016-06-09__interview-with-lee-byron-react-developer-at-facebook/images/Grommet_React_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-06-09__interview-with-lee-byron-react-developer-at-facebook/images/Grommet_React_original.png -------------------------------------------------------------------------------- /server/posts/2015-12-23__hacking-lunchtime-the-usdas-eat-school-lunch-ux-challenge/images/screenshot-4-1200x675.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2015-12-23__hacking-lunchtime-the-usdas-eat-school-lunch-ux-challenge/images/screenshot-4-1200x675.jpg -------------------------------------------------------------------------------- /server/posts/2016-03-21__designing-in-a-large-enterprise-company-part-1-design-a-very-overused-term/images/grommet-blog-1200x670.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-03-21__designing-in-a-large-enterprise-company-part-1-design-a-very-overused-term/images/grommet-blog-1200x670.jpg -------------------------------------------------------------------------------- /server/posts/2015-11-23__what-is-grommet/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2015/11/23/what-is-grommet", 3 | "title": "What is Grommet?", 4 | "author": "Eric Soderberg", 5 | "tags": [ 6 | "grommet", 7 | "reactjs", 8 | "javascript" 9 | ], 10 | "coverImage": "cover.jpg", 11 | "createdAt": "2015-11-23T19:59:25.865Z" 12 | } -------------------------------------------------------------------------------- /server/posts/2016-04-28__grommet-062-released/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/04/28/grommet-062-released", 3 | "createdAt": "2016-04-28T14:28:10.268Z", 4 | "title": "Grommet 0.6.2 Released", 5 | "author": "Alan Souza", 6 | "tags": [ 7 | "new version release" 8 | ], 9 | "coverImage": "new-version-release.jpg" 10 | } 11 | -------------------------------------------------------------------------------- /server/posts/2015-11-24__welcome-to-our-blog/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2015/11/24/welcome-to-our-blog", 3 | "createdAt": "2015-11-24T22:23:48.785Z", 4 | "title": "Welcome to our blog!", 5 | "author": "Bryan Jacquot", 6 | "tags": [ 7 | "grommet", 8 | "reactjs", 9 | "introduction" 10 | ], 11 | "coverImage": "cover.jpg" 12 | } 13 | -------------------------------------------------------------------------------- /server/posts/2016-04-18__the-great-grommet-podcast-episode-four-an-interview-with-digital-accessibility-pro-jennison-asuncion/images/podcast-blog-art.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grommet/grommet-blog/master/server/posts/2016-04-18__the-great-grommet-podcast-episode-four-an-interview-with-digital-accessibility-pro-jennison-asuncion/images/podcast-blog-art.jpg -------------------------------------------------------------------------------- /src/js/Blog.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | import React from 'react'; 4 | 5 | import App from 'grommet/components/App'; 6 | 7 | const Blog = (props) => { 8 | return ( 9 | 10 | {props.children} 11 | 12 | ); 13 | }; 14 | 15 | export default Blog; 16 | -------------------------------------------------------------------------------- /src/js/components/Loading.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Box from 'grommet/components/Box'; 4 | import SpinningIcon from 'grommet/components/icons/Spinning'; 5 | 6 | const Loading = () => { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | }; 13 | 14 | export default Loading; 15 | -------------------------------------------------------------------------------- /server/posts/2016-02-04__why-we-chose-react/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/02/04/why-we-chose-react", 3 | "createdAt": "2016-02-04T23:43:59.689Z", 4 | "title": "Why We Chose React", 5 | "author": "Bryan Jacquot", 6 | "tags": [ 7 | "comparison", 8 | "react", 9 | "angular", 10 | "grommet" 11 | ], 12 | "coverImage": "react_blog_image.jpg" 13 | } 14 | -------------------------------------------------------------------------------- /server/posts/2016-03-22__the-great-grommet-podcast-episode-three/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/03/22/the-great-grommet-podcast-episode-three", 3 | "createdAt": "2016-03-22T14:52:03.396Z", 4 | "title": "The Great Grommet Podcast, Episode Three", 5 | "author": "Eric Soderberg", 6 | "tags": [ 7 | "podcast", 8 | "grommet" 9 | ], 10 | "coverImage": "podcast-blog-art.jpg" 11 | } 12 | -------------------------------------------------------------------------------- /server/posts/2016-08-10__css-in-js-may-not-be-the-solution-to-all-your-problems/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/08/10/css-in-js-may-not-be-the-solution-to-all-your-problems", 3 | "createdAt": "2016-08-10T20:17:29.524Z", 4 | "title": "CSS in JS may not be the solution to all your problems", 5 | "author": "Alan Souza", 6 | "tags": [ 7 | "reactjs", 8 | "css", 9 | "javascript" 10 | ] 11 | } -------------------------------------------------------------------------------- /server/posts/2016-03-10__the-great-grommet-podcast-episode-two/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/03/10/the-great-grommet-podcast-episode-two", 3 | "createdAt": "2016-03-10T22:35:26.598Z", 4 | "title": "The Great Grommet Podcast, Episode Two", 5 | "author": "Chris Carlozzi", 6 | "tags": [ 7 | "podcast", 8 | "grommet", 9 | "enterprise design" 10 | ], 11 | "coverImage": "podcast-blog-art.jpg" 12 | } 13 | -------------------------------------------------------------------------------- /server/posts/2015-12-10__how-to-contribute-to-grommet-on-github/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2015/12/10/how-to-contribute-to-grommet-on-github", 3 | "createdAt": "2015-12-10T22:50:42.631Z", 4 | "title": "How to Contribute to Grommet on GitHub", 5 | "author": "Alan Souza", 6 | "tags": [ 7 | "github", 8 | "grommet", 9 | "contribute", 10 | "pull request" 11 | ], 12 | "coverImage": "laptop_code1.jpg" 13 | } 14 | -------------------------------------------------------------------------------- /server/posts/2016-02-12__why-you-should-be-friends-with-your-style-guide/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/02/12/why-you-should-be-friends-with-your-style-guide", 3 | "createdAt": "2016-02-12T22:27:11.194Z", 4 | "title": "Why You Should Be Friends with Your Style Guide", 5 | "author": "Tracy Barmore", 6 | "tags": [ 7 | "design", 8 | "style guide", 9 | "ux" 10 | ], 11 | "coverImage": "blog_image.jpg" 12 | } 13 | -------------------------------------------------------------------------------- /server/posts/2015-12-28__2016-responsive-design-trends-with-ethan-marcotte/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2015/12/28/2016-responsive-design-trends-with-ethan-marcotte", 3 | "createdAt": "2015-12-28T22:23:22.383Z", 4 | "title": "2016 Responsive Design Trends with Ethan Marcotte", 5 | "author": "Chris Carlozzi", 6 | "tags": [ 7 | "interview", 8 | "design", 9 | "trend" 10 | ], 11 | "coverImage": "option_4.jpg" 12 | } 13 | -------------------------------------------------------------------------------- /server/posts/2016-06-09__interview-with-lee-byron-react-developer-at-facebook/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/06/09/interview-with-lee-byron-react-developer-at-facebook", 3 | "createdAt": "2016-06-09T22:30:42.268Z", 4 | "title": "Interview with Lee Byron, React Developer at Facebook", 5 | "author": "Eric Soderberg", 6 | "tags": [ 7 | "react", 8 | "interview" 9 | ], 10 | "coverImage": "Grommet_React_original.png" 11 | } -------------------------------------------------------------------------------- /server/posts/2016-02-10__welcome-to-the-first-ever-great-grommet-podcast/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/02/10/welcome-to-the-first-ever-great-grommet-podcast", 3 | "createdAt": "2016-02-10T22:12:05.091Z", 4 | "title": "Welcome to the First-Ever Great Grommet Podcast!", 5 | "author": "Eric Soderberg", 6 | "tags": [ 7 | "podcast", 8 | "grommet", 9 | "introduction" 10 | ], 11 | "coverImage": "podcast-blog-art.jpg" 12 | } -------------------------------------------------------------------------------- /server/posts/2015-11-30__discover-grommet-at-hpe-discover-2015-in-london/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2015/11/30/discover-grommet-at-hpe-discover-2015-in-london", 3 | "createdAt": "2015-11-30T12:09:54.986Z", 4 | "title": "Discover Grommet at HPE Discover 2015 in London", 5 | "author": "Chris Carlozzi", 6 | "tags": [ 7 | "discover", 8 | "hpe", 9 | "grommet", 10 | "reactjs" 11 | ], 12 | "coverImage": "cover.jpg" 13 | } 14 | -------------------------------------------------------------------------------- /server/posts/2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2015/12/07/reflections-on-grommet-at-hpe-discover-2015-in-london", 3 | "createdAt": "2015-12-07T22:32:47.822Z", 4 | "title": "Reflections on Grommet at HPE Discover 2015 in London", 5 | "author": "Eric Soderberg", 6 | "tags": [ 7 | "review", 8 | "discover", 9 | "grommet" 10 | ], 11 | "coverImage": "london.jpg" 12 | } 13 | -------------------------------------------------------------------------------- /server/posts/2016-04-08__top-5-rules-for-giving-enterprise-apps-a-consumer-grade-ux/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/04/08/top-5-rules-for-giving-enterprise-apps-a-consumer-grade-ux", 3 | "createdAt": "2016-04-08T20:14:48.412Z", 4 | "title": "Top 5 Rules for Giving Enterprise Apps a Consumer-Grade UX", 5 | "author": "Bryan Jacquot", 6 | "tags": [ 7 | "ux", 8 | "enterprise", 9 | "rules" 10 | ], 11 | "coverImage": "5character.jpg" 12 | } 13 | -------------------------------------------------------------------------------- /src/js/components/social/SocialShare.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Anchor from 'grommet/components/Anchor'; 3 | 4 | export default class SocialShare extends Component { 5 | render () { 6 | const Icon = this.icon; 7 | const iconNode = ( 8 | 9 | ); 10 | 11 | return ( 12 | 13 | ); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /server/posts/2016-07-06__grommet-course-3-accessibility-and-internationalization/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/07/06/grommet-course-3-accessibility-and-internationalization", 3 | "createdAt": "2016-07-06T23:20:46.427Z", 4 | "title": "Grommet Course #3: Accessibility and Internationalization", 5 | "author": "Alan Souza", 6 | "tags": [ 7 | "a11y", 8 | "accessibility", 9 | "internationalization" 10 | ], 11 | "coverImage": "screenshot.png" 12 | } -------------------------------------------------------------------------------- /server/posts/2016-09-01__how-we-landed-on-jest-snapshot-testing-for-javascript/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/09/01/how-we-landed-on-jest-snapshot-testing-for-javascript", 3 | "createdAt": "2016-09-01T18:41:16.032Z", 4 | "title": "How we landed on Jest snapshot testing for JavaScript", 5 | "author": "Alan Souza", 6 | "tags": [ 7 | "reactjs", 8 | "jest", 9 | "testing", 10 | "javascript" 11 | ], 12 | "coverImage": "HP20141219607.jpg" 13 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **bower_components** 2 | node_modules 3 | **/dist*/** 4 | **/dist-bower*/** 5 | notes.txt 6 | .DS_Store 7 | .sass-cache 8 | *.flags.json 9 | *.iml 10 | .idea/** 11 | *.log 12 | *tmp* 13 | **sublime-project** 14 | **sublime-workspace** 15 | **requests.csv** 16 | **coverage** 17 | **lcov.info** 18 | src/js/baseIcons.js 19 | **/src/js/components/icons/base*/** 20 | **iconsMap** 21 | **index-icons** 22 | **.publish** 23 | server/css** 24 | server/server-routes.js 25 | -------------------------------------------------------------------------------- /server/posts/2016-03-31__grommet-training-series-part-1-getting-started-with-grommet/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/03/31/grommet-training-series-part-1-getting-started-with-grommet", 3 | "createdAt": "2016-03-31T20:09:16.991Z", 4 | "title": "Grommet Training Series Part 1: Getting Started With Grommet", 5 | "author": "Eric Soderberg", 6 | "tags": [ 7 | "training", 8 | "getting started", 9 | "grommet" 10 | ], 11 | "coverImage": "option1.jpg" 12 | } 13 | -------------------------------------------------------------------------------- /src/js/components/Error.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | import Box from 'grommet/components/Box'; 4 | import Notification from 'grommet/components/Notification'; 5 | 6 | const Error = (props) => { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | }; 13 | 14 | Error.propTypes = { 15 | message: PropTypes.string.isRequired 16 | }; 17 | 18 | export default Error; 19 | -------------------------------------------------------------------------------- /server/posts/2015-12-23__hacking-lunchtime-the-usdas-eat-school-lunch-ux-challenge/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2015/12/23/hacking-lunchtime-the-usdas-eat-school-lunch-ux-challenge", 3 | "createdAt": "2015-12-23T22:23:22.383Z", 4 | "title": "Hacking Lunchtime: The USDA's E.A.T School Lunch UX Challenge", 5 | "author": "Chris Carlozzi", 6 | "tags": [ 7 | "ux", 8 | "hacking", 9 | "challenge", 10 | "kids" 11 | ], 12 | "coverImage": "screenshot-4-1200x675.jpg" 13 | } 14 | -------------------------------------------------------------------------------- /src/js/components/social/RedditShare.js: -------------------------------------------------------------------------------- 1 | import SocialShare from './SocialShare'; 2 | import SocialReddit from 'grommet/components/icons/base/SocialReddit'; 3 | 4 | export default class RedditShare extends SocialShare { 5 | constructor (props) { 6 | super(props); 7 | 8 | this.name = 'Reddit'; 9 | this.icon = ( 10 | SocialReddit 11 | ); 12 | 13 | const url = encodeURIComponent(props.target); 14 | this.url = `https://www.reddit.com/submit?url=${url}`; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/js/components/social/TwitterShare.js: -------------------------------------------------------------------------------- 1 | import SocialShare from './SocialShare'; 2 | import SocialTwitter from 'grommet/components/icons/base/SocialTwitter'; 3 | 4 | export default class TwitterShare extends SocialShare { 5 | constructor (props) { 6 | super(props); 7 | 8 | this.name = 'Twitter'; 9 | this.icon = ( 10 | SocialTwitter 11 | ); 12 | 13 | const text = encodeURIComponent(props.target); 14 | this.url = `https://twitter.com/intent/tweet?text=${text}`; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/js/components/social/LinkedinShare.js: -------------------------------------------------------------------------------- 1 | import SocialShare from './SocialShare'; 2 | import SocialLinkedin from 'grommet/components/icons/base/SocialLinkedin'; 3 | 4 | export default class LinkedinShare extends SocialShare { 5 | constructor (props) { 6 | super(props); 7 | 8 | this.name = 'Linkedin'; 9 | this.icon = ( 10 | SocialLinkedin 11 | ); 12 | 13 | const url = encodeURIComponent(props.target); 14 | this.url = `https://www.linkedin.com/shareArticle?url=${url}`; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /server/posts/2016-03-21__designing-in-a-large-enterprise-company-part-1-design-a-very-overused-term/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/03/21/designing-in-a-large-enterprise-company-part-1-design-a-very-overused-term", 3 | "createdAt": "2016-03-21T20:56:46.509Z", 4 | "title": "Designing in a Large Enterprise Company, Part 1: Design, a Very Overused Term", 5 | "author": "Chris Carlozzi", 6 | "tags": [ 7 | "design", 8 | "enterprise", 9 | "ux" 10 | ], 11 | "coverImage": "grommet-blog-1200x670.jpg" 12 | } 13 | -------------------------------------------------------------------------------- /server/posts/2016-07-06__grommet-course-3-accessibility-and-internationalization/content.md: -------------------------------------------------------------------------------- 1 | Grommet course #3 is now available, we talk about accessibility and internationalization. Your feedback is appreciated either in the comments below or on our Slack channel. 2 | 3 | Topics covered: 4 | 1 - Improving navigation for Single Page Apps 5 | 2 - Improving element description for screen readers 6 | 3 - Using react-intl to translate 7 | 8 | 9 | 10 | -Alan -------------------------------------------------------------------------------- /server/posts/2016-04-18__the-great-grommet-podcast-episode-four-an-interview-with-digital-accessibility-pro-jennison-asuncion/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2016/04/18/the-great-grommet-podcast-episode-four-an-interview-with-digital-accessibility-pro-jennison-asuncion", 3 | "createdAt": "2016-04-18T14:56:38.292Z", 4 | "title": "The Great Grommet Podcast, Episode Four: An Interview with Digital Accessibility Pro Jennison Asuncion", 5 | "author": "Chris Carlozzi", 6 | "tags": [ 7 | "podcast", 8 | "grommet" 9 | ], 10 | "coverImage": "podcast-blog-art.jpg" 11 | } 12 | -------------------------------------------------------------------------------- /src/js/components/social/FacebookShare.js: -------------------------------------------------------------------------------- 1 | import SocialShare from './SocialShare'; 2 | import SocialFacebook from 'grommet/components/icons/base/SocialFacebook'; 3 | 4 | export default class FacebookShare extends SocialShare { 5 | constructor (props) { 6 | super(props); 7 | 8 | this.name = 'Facebook'; 9 | this.icon = ( 10 | SocialFacebook 11 | ); 12 | 13 | const link = encodeURIComponent(props.target); 14 | const redirectUri = encodeURIComponent('http://facebook.com/'); 15 | this.url = `https://www.facebook.com/dialog/feed?app_id=145634995501895&link=${link}&redirect_uri=${redirectUri}&display=popup`; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # grommet-blog 2 | 3 | An oddly simple blog implementation for Grommet. 4 | 5 | [WIP]: We are still working on the manage aspect of the blog and also figuring out how others can reuse it in a click of a button. 6 | 7 | ## How To 8 | 9 | To run this application, execute the following commands: 10 | 11 | 1. Install NPM modules 12 | 13 | ``` 14 | $ cd grommet-blog 15 | $ npm install 16 | ``` 17 | 18 | 2. Start the server 19 | 20 | ``` 21 | $ npm start 22 | ``` 23 | 24 | 3. Start the UI development server 25 | 26 | ``` 27 | $ gulp dev 28 | ``` 29 | 30 | 4. Build project 31 | 32 | ``` 33 | $ npm run build 34 | ``` 35 | 36 | -------------------------------------------------------------------------------- /src/scss/index.scss: -------------------------------------------------------------------------------- 1 | //for hpe theme, use the following import instead 2 | $readable-text-width: 960px; 3 | $form-width: 800px; 4 | 5 | @import 'highlight-js.github'; 6 | @import 'grommet/scss/vanilla/index'; 7 | 8 | .post-body { 9 | width: $readable-text-width; 10 | max-width: 100%; 11 | } 12 | 13 | blockquote { 14 | max-width: $readable-text-width; 15 | border-left: 4px solid nth($brand-neutral-colors, 1); 16 | background-color: #f8f8f8; 17 | padding: 1px $inuit-base-spacing-unit - 4px; 18 | display: flex; 19 | } 20 | 21 | .grommet a:not(.anchor):hover, 22 | a.post-link { 23 | &:hover { 24 | text-decoration: none; 25 | } 26 | } 27 | 28 | iframe { 29 | max-width: 100%; 30 | } 31 | -------------------------------------------------------------------------------- /src/js/utils/blog.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | const DEFAULT_TITLE = 'Grommet Blog'; 4 | 5 | export function setDocumentTitle (title) { 6 | if (document) { 7 | if (title && typeof title === 'string') { 8 | title = `${title} | ${DEFAULT_TITLE}`; 9 | } else { 10 | title = DEFAULT_TITLE; 11 | } 12 | document.title = title; 13 | } 14 | } 15 | 16 | export function getImageAsBase64 (image) { 17 | return new Promise((resolve) => { 18 | const reader = new FileReader(); 19 | reader.onload = function (event) { 20 | resolve(event.target.result); 21 | }.bind(this); 22 | reader.readAsDataURL(image.file); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /server/posts/2015-11-30__discover-grommet-at-hpe-discover-2015-in-london/content.md: -------------------------------------------------------------------------------- 1 | I'm excited to be in the UK this week with teammate, Eric Soderberg demoing and answering your questions about Grommet at HPE Discover '15 in London. Come by and say hi! 2 | 3 | ### HPE Discover 2015 4 | * **Date**: December 1-3 5 | * **Location**: [ExCeL London](http://excel.london/) 6 | 7 | Where's Grommet? Come find us in the Transformation Zone. 8 | 9 | More Info on HPE Discover: [hpe.com/events/discover](https://www.hpe.com/events/discover/) 10 | 11 | if you're a fan, or just want to add another open source project sticker to your laptop, we'll have Grommet buttons and stickers for anyone that stops by the booth. 12 | 13 | ![](buttons-225x300.jpg) 14 | 15 | See you in London! -------------------------------------------------------------------------------- /src/js/components/manage/PreviewPost.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2015 Hewlett Packard Enterprise Development LP 2 | 3 | import React, { PropTypes } from 'react'; 4 | 5 | import Box from 'grommet/components/Box'; 6 | import Layer from 'grommet/components/Layer'; 7 | 8 | import PostBody from '../PostBody'; 9 | 10 | const PreviewPost = (props) => { 11 | const { post, onClose } = props; 12 | 13 | return ( 14 | 16 | 17 | 18 | 19 | 20 | ); 21 | }; 22 | 23 | PreviewPost.propTypes = { 24 | onClose: PropTypes.func.isRequired, 25 | post: PropTypes.object 26 | }; 27 | 28 | export default PreviewPost; 29 | -------------------------------------------------------------------------------- /src/js/BlogContext.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | import React, { Component, PropTypes } from 'react'; 3 | import { Router } from 'react-router'; 4 | 5 | import store from './store'; 6 | 7 | export default class BlogContext extends Component { 8 | getChildContext () { 9 | return { asyncData: this.props.asyncData }; 10 | } 11 | 12 | componentDidMount () { 13 | store.setUseContext(false); 14 | } 15 | 16 | render () { 17 | const {tag, renderProps} = this.props; 18 | 19 | let Tag = tag || Router; 20 | return ( 21 | 22 | ); 23 | } 24 | }; 25 | 26 | BlogContext.propTypes = { 27 | asyncData: PropTypes.any, 28 | renderProps: PropTypes.any.isRequired 29 | }; 30 | 31 | BlogContext.childContextTypes = { 32 | asyncData: PropTypes.any 33 | }; 34 | -------------------------------------------------------------------------------- /src/js/components/NotFound.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Article from 'grommet/components/Article'; 4 | import Section from 'grommet/components/Section'; 5 | import Header from 'grommet/components/Header'; 6 | import Paragraph from 'grommet/components/Paragraph'; 7 | 8 | import BlogHeader from './Header'; 9 | import Footer from './Footer'; 10 | 11 | const NotFound = () => { 12 | return ( 13 |
14 | 15 |
16 |

Oops!

17 |

This page can't be found.

18 | 19 | It looks like nothing was found at this location. 20 | Maybe try searching for what you need? 21 | 22 |
23 |
24 |
25 | ); 26 | }; 27 | 28 | export default NotFound; 29 | -------------------------------------------------------------------------------- /server/posts/2016-03-31__grommet-training-series-part-1-getting-started-with-grommet/content.md: -------------------------------------------------------------------------------- 1 | Our own Grommet developer, Alan Souza, recently kicked off the Grommet training series with our first tutorial. In it, Alan explains how viewers can get started with Grommet. 2 | 3 | By the end of this video you will be able to: 4 | 5 | * Install Grommet using Node/NPM 6 | * Create an initial application structure using Grommet CLI 7 | * Create a simple to-do app 8 | * Test Accessibility in your newly created app 9 | 10 | Note: This video is intended for viewers with knowledge in Javascript, Node.JS and [React](/post/2016/02/04/why-we-chose-react). 11 | 12 | 13 | 14 | Stay tuned for more Grommet courses and be sure to provide us with any feedback or questions, as well as any topics you would like covered! -------------------------------------------------------------------------------- /src/js/components/manage/ManageDeletePost.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2015 Hewlett Packard Enterprise Development LP 2 | 3 | import React, { PropTypes } from 'react'; 4 | import Paragraph from 'grommet/components/Paragraph'; 5 | import LayerForm from 'grommet-templates/components/LayerForm'; 6 | 7 | const ManageDeletePost = (props) => { 8 | const { post, onCancel, onDelete } = props; 9 | return ( 10 | 12 |
13 | Are you sure you want to 14 | remove {post.title} post? 15 |
16 |
17 | ); 18 | }; 19 | 20 | ManageDeletePost.propTypes = { 21 | post: PropTypes.object.isRequired, 22 | onCancel: PropTypes.func.isRequired, 23 | onDelete: PropTypes.func.isRequired 24 | }; 25 | 26 | export default ManageDeletePost; 27 | -------------------------------------------------------------------------------- /src/js/index.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | import 'whatwg-fetch'; 3 | import { polyfill as promisePolyfill } from 'es6-promise'; 4 | promisePolyfill(); 5 | 6 | import '../scss/index.scss'; 7 | 8 | import React from 'react'; 9 | import { render } from 'react-dom'; 10 | import { match } from 'react-router'; 11 | 12 | import routes from './routes'; 13 | import history from './RouteHistory'; 14 | import BlogContext from './BlogContext'; 15 | 16 | let element = document.getElementById('content'); 17 | 18 | let asyncData; 19 | let asyncDataNode = document.getElementById('asyncData'); 20 | if (asyncDataNode) { 21 | asyncData = JSON.parse(asyncDataNode.textContent); 22 | } 23 | 24 | match({ history, routes }, (error, redirectLocation, renderProps) => { 25 | render( 26 | , 27 | element 28 | ); 29 | }); 30 | 31 | document.body.classList.remove('loading'); 32 | -------------------------------------------------------------------------------- /src/js/components/manage/ManageCancelChangePost.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2015 Hewlett Packard Enterprise Development LP 2 | 3 | import React, { PropTypes } from 'react'; 4 | import Paragraph from 'grommet/components/Paragraph'; 5 | import LayerForm from 'grommet-templates/components/LayerForm'; 6 | 7 | const ManageCancelChangePost = (props) => { 8 | const { post, onCancel, onConfirm } = props; 9 | return ( 10 | 12 |
13 | Are you sure you want to 14 | cancel {post.action} {post.title} post? 15 | 16 |
17 |
18 | ); 19 | }; 20 | 21 | ManageCancelChangePost.propTypes = { 22 | post: PropTypes.object.isRequired, 23 | onCancel: PropTypes.func.isRequired, 24 | onConfirm: PropTypes.func.isRequired 25 | }; 26 | 27 | export default ManageCancelChangePost; 28 | -------------------------------------------------------------------------------- /grommet-toolbox.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import webpack from 'webpack'; 3 | 4 | export default { 5 | copyAssets: [ 6 | 'src/index.html', 7 | { 8 | asset: 'src/img/**', 9 | dist: 'dist/img/' 10 | }, 11 | { 12 | asset: 'node_modules/grommet/img/shortcut-icon.png', 13 | dist: 'dist/img/' 14 | }, 15 | { 16 | asset: 'node_modules/grommet/img/mobile-app-icon.png', 17 | dist: 'dist/img/' 18 | } 19 | ], 20 | jsAssets: ['src/js/**/*.js'], 21 | mainJs: 'src/js/index.js', 22 | mainScss: 'src/scss/index.scss', 23 | devServerPort: 9070, 24 | devServerProxy: { 25 | "/api/post/*": 'http://localhost:8070' 26 | }, 27 | webpack: { 28 | resolve: { 29 | root: [ 30 | path.resolve(__dirname, './node_modules') 31 | ] 32 | }, 33 | plugins: [ 34 | new webpack.ProvidePlugin({ 35 | 'fetch': 'exports?self.fetch!whatwg-fetch' 36 | }) 37 | ] 38 | }, 39 | alias: { 40 | 'grommet/scss': path.resolve(__dirname, '../grommet/src/scss'), 41 | 'grommet': path.resolve(__dirname, '../grommet/src/js') 42 | }, 43 | devPreprocess: ['set-webpack-alias'], 44 | scsslint: true 45 | }; 46 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: '5' 3 | sudo: false 4 | before_script: npm install -g gulp 5 | script: gulp dist 6 | after_success: 7 | - | 8 | if [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then 9 | git config credential.helper "store --file=.git/credentials" 10 | echo "https://${GH_TOKEN}:@github.com" > .git/credentials 11 | git config --global user.name "Grommet Community Bot" 12 | git config --global user.email "asouza@hp.com" 13 | gulp release:heroku 14 | fi 15 | env: 16 | global: 17 | secure: ioEl3x6z0xdOe6Lxg0DdHzcvvZ00iZrqBTOPYcEVRSOcM4qaN+ffHOpZ1fBY5ZvMqrUWz7XPZiSjPh8pHZpvUBYC0goEZoqQibSxMRzM8PPvpT8ABJ6qYHgG3EQ+8Uc5xk68bWVBclo0JxCHGfRcXk7fGb3tH7CZ4hAWdBu9p7eazmddBsbEM6ASdaSeklapLBS+aqlUYbfkxIi7MywKSHUOCgZZ3GRWVKz2zPEugBm5yeOADAGuas8qBb3xDGa+s8Zja8a0ZvCgMMK5gbgDN3r7qW+Kd4lQzCqGRRe3Md6kwIz9h1diQoxXsC7DIjKmn+/BoJ1xdUbm6rX+2K1sqwzwC7+q7ooKpPva8BwSVZv5o4BCYQjmWq++IIT5aYnWROHkH+14h91rJprQIDtWn4rldB8bOlt5HYTX0x7OQNCi3Xopw3QF/h3DnWhjiPU92f2e35wc+LUozM+gqGjkKOsH9O8O3Fd4+D9/Ae5gS2o5l0woeiHUtUOtm+TyAwEh7E/bOAxp/FJvYKz3qbLxmrXnGTwu398HXS3skY4YTXyKKx7mGSwAjUNiMEZgX7tOAZb3g/JX7XIPKXsO1BEhYTPXX3QCZ3G9iISqGg3x4c/Gl2Xhu+RsxZeF/zXgeB4YzIi3NDF4FGwZWErYQZkQBxRdCxdXJdh3105Fsjcrjvs= 18 | -------------------------------------------------------------------------------- /src/js/components/manage/ManageAddPost.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. 2 | 3 | import React, { Component } from 'react'; 4 | 5 | import PostForm from './PostForm'; 6 | 7 | import store from '../../store'; 8 | import history from '../../RouteHistory'; 9 | 10 | export default class ManageAddPost extends Component { 11 | constructor () { 12 | super(); 13 | 14 | this._onAddPost = this._onAddPost.bind(this); 15 | this._onAddPostSucceed = this._onAddPostSucceed.bind(this); 16 | this._onAddPostFailed = this._onAddPostFailed.bind(this); 17 | 18 | this.state = { 19 | error: undefined 20 | }; 21 | } 22 | 23 | _onAddPost (post) { 24 | store.addPost(post).then( 25 | this._onAddPostSucceed, this._onAddPostFailed 26 | ); 27 | } 28 | 29 | _onAddPostSucceed () { 30 | history.push('/manage'); 31 | } 32 | 33 | _onAddPostFailed () { 34 | this.setState({ 35 | error: 'Could not add post, please try again.' 36 | }); 37 | } 38 | 39 | render () { 40 | return ( 41 | 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /server/posts/2016-04-28__grommet-062-released/content.md: -------------------------------------------------------------------------------- 1 | Grommet 0.6.2 has been released! This latest version includes the following changes: 2 | 3 | * **Enhanced Components:** Article, Box, Button, Chart, CheckBox, Distribution, FormField, Header, Image, Label, Layer, Menu, Meter, Paragraph, SkipLinks, Tags, Tile, Video 4 | * **New Components:** Markdown, WorldMap, SocialShare, Quote, Value 5 | * New set of icons 6 | * Removed deprecated features 7 | * Added support for grommet-toolbox 8 | * Accessibility improvements to Icons 9 | * Added tint (t) option to colored box 10 | 11 | It’s great to see Grommet’s momentum building month after month. It was a solid month for contributions with 235 commits and 42 pull requests accepted. Let’s put our virtual hands together for our amazing contributors: [@allisonday](https://github.com/codeswan), [@jackie](https://github.com/jwijay), [@eabay](https://github.com/eabay), [@son](https://github.com/phuson), [@nickvanmeter](https://github.com/nickjvm), [@primozs](https://github.com/primozs), [@alex.mejias](https://github.com/karatechops), [@kentsalcedo](https://github.com/kentsalcedo). 12 | 13 | P.S: Sorry about skipping 0.6.0 and 0.6.1. We are still facing intermittent issues on NPM with missing icons. 0.6.2 has been tested and is already being used in production. 14 | -------------------------------------------------------------------------------- /src/js/routes.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | import Blog from './Blog'; 4 | import Home from './Home'; 5 | import Archive from './components/Archive'; 6 | import NotFound from './components/NotFound'; 7 | import Post from './components/Post'; 8 | import Search from './components/Search'; 9 | import Manage from './components/manage/Manage'; 10 | import ManageAddPost from './components/manage/ManageAddPost'; 11 | import ManageEditPost from './components/manage/ManageEditPost'; 12 | 13 | export default [ 14 | { path: '/', component: Blog, 15 | indexRoute: { component: Home }, 16 | childRoutes: [ 17 | { 18 | path: 'archive', component: Archive, 19 | childRoutes: [ 20 | { path: 'author/:authorName' }, 21 | { path: 'tag/:tagName' }, 22 | { path: ':year' }, 23 | { path: ':year/:month' }, 24 | { path: ':year/:month/:day' } 25 | ] 26 | }, 27 | { path: 'post/*', component: Post }, 28 | { path: 'search', component: Search }, 29 | { path: 'manage', component: Manage }, 30 | { path: 'manage/post/add', component: ManageAddPost }, 31 | { path: 'manage/post/edit/*', component: ManageEditPost }, 32 | { path: '*', component: NotFound } 33 | ] 34 | } 35 | ]; 36 | -------------------------------------------------------------------------------- /src/js/components/manage/Header.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | import React, { Component } from 'react'; 4 | import { Link } from 'react-router'; 5 | 6 | import Anchor from 'grommet/components/Anchor'; 7 | import Box from 'grommet/components/Box'; 8 | import Heading from 'grommet/components/Heading'; 9 | import Header from 'grommet/components/Header'; 10 | import Title from 'grommet/components/Title'; 11 | import GrommetLogo from 'grommet/components/icons/Grommet'; 12 | 13 | import Add from 'grommet/components/icons/base/Add'; 14 | 15 | import history from '../../RouteHistory'; 16 | 17 | export default class BlogHeader extends Component { 18 | 19 | _onAddPost (event) { 20 | event.preventDefault(); 21 | history.push('/manage/post/add'); 22 | } 23 | 24 | render () { 25 | 26 | const logo = ( 27 | 28 | 29 | <GrommetLogo a11yTitle=""/> 30 | <Heading tag="h3">Blog</Heading> 31 | 32 | 33 | ); 34 | 35 | return ( 36 |
38 | {logo} 39 | 40 | } onClick={this._onAddPost} 41 | a11yTitle='Add Post' /> 42 | 43 |
44 | ); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /server/posts/2016-03-10__the-great-grommet-podcast-episode-two/content.md: -------------------------------------------------------------------------------- 1 | Welcome back to the second installment of the [Great Grommet Podcast](https://blog.grommet.io/post/2016/02/10/welcome-to-the-first-ever-great-grommet-podcast). This week Eric and I had a lot of great topics to discuss. We touched on how Grommet got started and answered one of the most common questions we get, “What makes Grommet so great for the enterprise?” 2 | 3 | 4 | 5 | Here’s an overview of the topics we discussed in this episode: 6 | 7 | * **0:59** — There’s so much out there; why use Grommet? 8 | * **5:15** — The login screen dilemma…The issue that brought Grommet into the world 9 | * **7:30** — Driving an organization and development from a design leadership standpoint 10 | * **10:25** — Having an open-source mindset 11 | * **14:11** — How Grommet is designed for the enterprise 12 | * **19:00** — Contribute to Grommet on Github 13 | 14 | That’s all we have for you this week! Stay tuned for the next episode in a couple weeks and be sure to leave us some comments. Since our podcast is just getting started we’d love your feedback on what you like and what you’d like to hear more about. Bring on the suggestions! 15 | 16 | Lastly, a special thanks to Grommet contributor Yousef for kicking off this week’s podcast. 17 | -------------------------------------------------------------------------------- /server/posts/2016-03-22__the-great-grommet-podcast-episode-three/content.md: -------------------------------------------------------------------------------- 1 | Eric and Chris are back at it again with the third installment of the Great Grommet Podcast and are joined by special guest and colleague Alan Souza. Alan is celebrating his one-year anniversary with Grommet and gives a previews of his upcoming presentation at the Annual International Technology and Persons with Disabilities Conference on accessibility. 2 | 3 | 4 | 5 | Here’s an overview of the topics discussed in this episode: 6 | 7 | * **0:30** — Alan Souza shares details on his CSUN accessibility presentation 8 | * **6:00** — Rate and Review the Great Grommet Podcast on iTunes! 9 | * **7:40** — Grommet 0.5.4 Release Notes 10 | * **10:00** — Overview of the creation of the Hyper Converged 380 System from Hewlett Packard Enterprise 11 | * **14:00** — Blogging with Grommet 12 | 13 | We have a lot of exciting stuff coming down the pipeline from Grommet so stay tuned for upcoming episodes! As always, any feedback on what you like and what you’d like to hear more about is greatly appreciated. We love your suggestions! Lastly, make sure to [rate and review the Great Grommet Podcast on iTunes](https://itunes.apple.com/us/podcast/great-grommet-podcast/id1089989263). 14 | 15 | A special thanks to Grommet contributor Jackie for doing the intro and to bensound.com for the music. 16 | -------------------------------------------------------------------------------- /src/js/RouteHistory.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP 2 | 3 | import { browserHistory } from 'react-router'; 4 | let history = browserHistory; 5 | 6 | // We have our own history implementation so we can insert a prefix. 7 | // This allows sharing web servers and using sub domains with less 8 | // application awareness. 9 | 10 | let appPrefix = ''; 11 | 12 | function addPrefix (location) { 13 | let result = location; 14 | if (appPrefix.length > 0) { 15 | if (typeof location === 'string') { 16 | if (location.slice(0, appPrefix.length) !== appPrefix) { 17 | result = (appPrefix + location); 18 | } 19 | } else { 20 | if (location.pathname.slice(0, appPrefix.length) !== appPrefix) { 21 | result = { ...location, pathname: appPrefix + location.pathname }; 22 | } 23 | } 24 | } 25 | return result; 26 | } 27 | 28 | function removePrefix (location) { 29 | let result = location; 30 | if (appPrefix.length > 0 && 31 | location.pathname.slice(0, appPrefix.length) === appPrefix) { 32 | result = { ...location, pathname: location.pathname.slice(appPrefix.length) }; 33 | } 34 | return result; 35 | } 36 | 37 | export default { 38 | ...history, 39 | listen: (handler) => { 40 | return history.listen((location) => { 41 | handler(removePrefix(location)); 42 | }); 43 | }, 44 | push: (location) => { 45 | history.push(addPrefix(location)); 46 | }, 47 | replace: (location) => { 48 | history.replace(addPrefix(location)); 49 | }, 50 | prefix: (prefix) => { 51 | appPrefix = prefix; 52 | }, 53 | makeHref: (path) => `${appPrefix}${path}` 54 | }; 55 | -------------------------------------------------------------------------------- /server/posts/2016-02-10__welcome-to-the-first-ever-great-grommet-podcast/content.md: -------------------------------------------------------------------------------- 1 | We’ve had a blast getting Grommet up and running over the past year, and we hope you’ve enjoyed what we’ve shared on the blog. It’s been fun so far but we’re just getting started! 2 | 3 | Embedded below you can treat your ears to the first-ever Great Grommet podcast. This week’s episode features myself along with the dulcet tones of my Grommet comrade Chris Carlozzi. 4 | 5 | 6 | 7 | Here’s a quick glimpse at some of what we covered: 8 | 9 | * What Grommet is and who we’re building it for (2:39) 10 | * Discussing Ethan Marcotte’s Grommet interview about Responsive Design (7:35) 11 | * Putting yourself in a problem-solving mindset (11:00) 12 | * How people are contributing to Grommet and helping it grow and evolve (16:30) 13 | * Being mobile first in design (18:30) 14 | 15 | We hope to crank out a new episode every couple weeks or so. If we’re lucky enough, we might even convince [Alan](https://twitter.com/alansouzati) to lay down some mad Brazilian beats on his accordion. 16 | 17 | Let us know what you think in the comments and definitely suggest any topics you’d like us to discuss, on Grommet or otherwise, in the future! 18 | 19 | P.S. Thanks to Erhan Abay (a Grommet contributor) for introducing our first podcast and to [Benjamin Tissot](https://twitter.com/Bensound) for our intro and closing music. -------------------------------------------------------------------------------- /src/js/components/Header.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | import React, { Component } from 'react'; 4 | import { Link } from 'react-router'; 5 | 6 | import Box from 'grommet/components/Box'; 7 | import Anchor from 'grommet/components/Anchor'; 8 | import Header from 'grommet/components/Header'; 9 | import Heading from 'grommet/components/Heading'; 10 | import Title from 'grommet/components/Title'; 11 | import GrommetLogo from 'grommet/components/icons/Grommet'; 12 | 13 | import history from '../RouteHistory'; 14 | 15 | import Search from 'grommet/components/icons/base/Search'; 16 | import Archive from 'grommet/components/icons/base/Archive'; 17 | 18 | export default class BlogHeader extends Component { 19 | 20 | _onSearch (event) { 21 | event.preventDefault(); 22 | history.push('/search'); 23 | } 24 | 25 | _onArchive (event) { 26 | event.preventDefault(); 27 | history.push('/archive'); 28 | } 29 | 30 | render () { 31 | 32 | const logo = ( 33 | 34 | 35 | <GrommetLogo a11yTitle=""/> 36 | <Heading tag="h3">Blog</Heading> 37 | 38 | 39 | ); 40 | 41 | const search = ( 42 | } href="/search" onClick={this._onSearch} /> 43 | ); 44 | 45 | const archive = ( 46 | } href="/archive" onClick={this._onArchive} /> 47 | ); 48 | 49 | return ( 50 |
52 | {logo} 53 | 54 | {search} 55 | {archive} 56 | 57 |
58 | ); 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grommet-blog", 3 | "version": "0.1.0", 4 | "main": "src/js/index.js", 5 | "license": "Apache-2.0", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/grommet/grommet-blog.git" 9 | }, 10 | "engines": { 11 | "node": ">= 5.0.0", 12 | "npm": ">= 3" 13 | }, 14 | "dependencies": { 15 | "babel-plugin-array-includes": "^2.0.3", 16 | "babel-plugin-transform-object-rest-spread": "^6.5.0", 17 | "babel-preset-es2015": "^6.3.13", 18 | "babel-preset-react": "^6.3.13", 19 | "babel-register": "^6.5.2", 20 | "basic-auth-connect": "^1.0.0", 21 | "body-parser": "^1.10.0", 22 | "busboy-body-parser": "0.0.10", 23 | "classnames": "^2.2.3", 24 | "compression": "^1.4.4", 25 | "connect-timeout": "^1.7.0", 26 | "cookie-parser": "^1.3.4", 27 | "del": "^2.2.0", 28 | "ejs": "^2.4.1", 29 | "es6-promise": "^3.2.1", 30 | "express": "^4.10.6", 31 | "express-sslify": "^1.0.1", 32 | "fecha": "^2.0.0", 33 | "fs-extra": "^0.28.0", 34 | "github": "^1.1.2", 35 | "grommet": "https://github.com/grommet/grommet/tarball/stable", 36 | "grommet-templates": "https://github.com/grommet/grommet-templates/tarball/stable", 37 | "highlight.js": "^9.2.0", 38 | "lunr": "^0.6.0", 39 | "mime-types": "^2.1.11", 40 | "morgan": "^1.5.0", 41 | "node-emoji": "^1.3.1", 42 | "node-sass": "^3.4.2", 43 | "react-disqus-thread": "^0.4.0", 44 | "react-router": "^2.0.0", 45 | "rimraf": "^2.5.2", 46 | "simple-git": "^1.27.0" 47 | }, 48 | "devDependencies": { 49 | "argv": "0.0.2", 50 | "del": "^2.2.0", 51 | "grommet-toolbox": "^0.1.13", 52 | "gulp": "^3.9.0", 53 | "gulp-git": "^1.7.0", 54 | "mkdirp": "^0.5.1" 55 | }, 56 | "scripts": { 57 | "build": "gulp dist", 58 | "start": "node server/server.js" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | parser: babel-eslint 3 | 4 | plugins: 5 | - react 6 | 7 | ecmaFeatures: 8 | jsx: true 9 | 10 | env: 11 | browser: true 12 | node: true 13 | 14 | globals: 15 | __DEV__: true 16 | __THEME__: true 17 | __DEV_MODE__: true 18 | __SOCKET_HOST__: true 19 | IntlPolyfill: true 20 | Modernizr: true 21 | describe: true 22 | it: true 23 | beforeEach: true 24 | afterEach: true 25 | before: true 26 | after: true 27 | 28 | rules: 29 | # ERRORS 30 | space-before-blocks: 2 31 | indent: [2, 2, { SwitchCase: 1 }] 32 | brace-style: 2 33 | comma-dangle: 2 34 | no-unused-expressions: 2 35 | eol-last: 2 36 | dot-notation: 2 37 | consistent-return: 2 38 | no-unused-vars: [2, args: none] 39 | semi: [2, "always"] 40 | 41 | # DISABLED 42 | max-len: 0 43 | #change soon back to max-len: [1, 80] 44 | no-underscore-dangle: 0 45 | new-cap: 0 46 | no-use-before-define: 0 47 | key-spacing: 0 48 | eqeqeq: 0 49 | strict: 0 50 | space-unary-ops: 0 51 | yoda: 0 52 | no-loop-func: 0 53 | no-trailing-spaces: 0 54 | no-multi-spaces: 0 55 | no-shadow: 0 56 | no-alert: 0 57 | no-process-exit: 0 58 | no-extend-native: 0 59 | block-scoped-var: 0 60 | quotes: 0 61 | jsx-quotes: 0 62 | 63 | # REACT DISABLED 64 | react/display-name: 0 65 | react/jsx-sort-prop-types: 0 66 | react/prop-types: 0 67 | react/no-did-mount-set-state: 0 68 | react/no-did-update-set-state: 0 69 | react/jsx-max-props-per-line: 0 70 | react/jsx-sort-props: 0 71 | react/no-multi-comp: 0 72 | react/jsx-boolean-value: 0 73 | react/no-danger: 0 74 | 75 | react/jsx-curly-spacing: 1 76 | react/jsx-no-duplicate-props: 1 77 | react/jsx-no-undef: 1 78 | react/jsx-uses-react: 1 79 | react/jsx-uses-vars: 1 80 | react/no-unknown-property: 1 81 | react/react-in-jsx-scope: 1 82 | react/require-extension: 1 83 | react/self-closing-comp: 1 84 | react/sort-comp: 1 85 | react/wrap-multilines: 1 86 | -------------------------------------------------------------------------------- /server/posts/2015-11-23__what-is-grommet/content.md: -------------------------------------------------------------------------------- 1 | If you were to give me just one sentence to describe Grommet, I would say it is the most advanced open source UX framework available for enterprise applications. To give a more complete explanation of what Grommet is, I'll step back and explain why we created it. 2 | 3 | Over the years at HP we had customers come to us saying to say various HP products wouldn't integrate well with each other because their UIs were very different, sometimes dramatically so. With this problem in mind, we wanted to create a single offering that would give customers the ability to create a UI with consistent look and feel in their applications that still provided robust UX design capabilities. Our goal was to create something for UX developers that had consumer-grade capabilities with an enterprise user experience framework. 4 | 5 | To address this problem, we took UI code from certain of its products, including the HP OneView IT management software, and packaged it into a reusable library in the form of Grommet. Simultaneously, it published a formal [style guide](https://grommet.github.io/docs/resources) to help developers build applications with consistent UIs. 6 | 7 | Grommet's design is highly modular, allowing developers to use just the parts of Grommet that are most applicable to their application. Users can benefit from using Grommet based on the needs of their users and applications, from referencing the style guide and its basic elements to complete adoption of the platform. 8 | 9 | We feel we've created something special and to back that up, all Hewlett Packard Enterprise software will ship with UIs based on Grommet. We encourage everyone who uses the Grommet open source code – either inside HP or out – to help expand and improve the framework. 10 | 11 | Ready to give Grommet a go? Head on over to our "[Hello World](https://grommet.github.io/docs/hello-world)" guide give it a try using the handy codepen template. For any questions about Grommet as you start tinkering, ping us on our Slack channel at [slackin.grommet.io](http://slackin.grommet.io). 12 | -------------------------------------------------------------------------------- /server/posts/2015-12-23__hacking-lunchtime-the-usdas-eat-school-lunch-ux-challenge/content.md: -------------------------------------------------------------------------------- 1 | The United States Department of Agriculture (USDA) is looking for a few good UX developers to help kids across the country get better access to school meal programs. The Electronic Application School (EAT) Lunch UX Challenge, hosted on [DevPost](http://devpost.com/), invites UX devs to create the USDA's first-ever model electronic application for households that apply for free or reduced-price school meals. 2 | 3 | Households traditionally apply for these meals through paper or online applications to their respective schools. U.S. government assistance subsidizes all program meals and receives millions of these applications each year. But according to the USDA, the application and approval process is less than smooth: 4 | 5 | > Due to issues with reporting, calculating, and processing, many applications contain errors that result in incorrect eligibility decisions for children. 6 | The Food and Nutrition Service (FNS) offers a prototype paper application on its website, and thousands of school districts have adopted or modified that application for their own use. Many districts also offer online applications, but the FNS does not have an electronic prototype for them to use as a model. 7 | 8 | Developers are tasked with creating a forward-looking, web-based application form using personalized behavioral prompts, UX best practices, and edit-checks to assist in accurate form completion. The ideal application form will help facilitate access to program benefits for eligible children and strengthen program integrity by reducing application errors. 9 | 10 | While warm-fuzzies will abound for anyone who helps tackle this challenge, the USDA is also offering $50,000 in cash prizes, with the best idea taking home a cool $20,000. 11 | 12 | If you’re interested in participating, head over to the EAT School Lunch UX Challenge [page on DevPost](http://lunchux.devpost.com/). Submissions are open now through March 1, 2016. 13 | 14 | -------------------------------------------------------------------------------- /src/scss/highlight-js.github.scss: -------------------------------------------------------------------------------- 1 | .hljs { 2 | display: block; 3 | overflow-x: auto; 4 | padding: 0.5em; 5 | color: #333; 6 | background: #f8f8f8; 7 | -webkit-text-size-adjust: none; 8 | } 9 | 10 | .hljs-comment, 11 | .diff .hljs-header { 12 | color: #998; 13 | font-style: italic; 14 | } 15 | 16 | .hljs-keyword, 17 | .css .rule .hljs-keyword, 18 | .hljs-winutils, 19 | .nginx .hljs-title, 20 | .hljs-subst, 21 | .hljs-request, 22 | .hljs-status { 23 | color: #333; 24 | font-weight: bold; 25 | } 26 | 27 | .hljs-number, 28 | .hljs-hexcolor, 29 | .ruby .hljs-constant { 30 | color: #008080; 31 | } 32 | 33 | .hljs-string, 34 | .hljs-tag .hljs-value, 35 | .hljs-doctag, 36 | .tex .hljs-formula { 37 | color: #d14; 38 | } 39 | 40 | .hljs-title, 41 | .hljs-id, 42 | .scss .hljs-preprocessor { 43 | color: #900; 44 | font-weight: bold; 45 | } 46 | 47 | .hljs-list .hljs-keyword, 48 | .hljs-subst { 49 | font-weight: normal; 50 | } 51 | 52 | .hljs-class .hljs-title, 53 | .hljs-type, 54 | .vhdl .hljs-literal, 55 | .tex .hljs-command { 56 | color: #458; 57 | font-weight: bold; 58 | } 59 | 60 | .hljs-tag, 61 | .hljs-tag .hljs-title, 62 | .hljs-rule .hljs-property, 63 | .django .hljs-tag .hljs-keyword { 64 | color: #000080; 65 | font-weight: normal; 66 | } 67 | 68 | .hljs-attribute, 69 | .hljs-variable, 70 | .lisp .hljs-body, 71 | .hljs-name { 72 | color: #008080; 73 | } 74 | 75 | .hljs-regexp { 76 | color: #009926; 77 | } 78 | 79 | .hljs-symbol, 80 | .ruby .hljs-symbol .hljs-string, 81 | .lisp .hljs-keyword, 82 | .clojure .hljs-keyword, 83 | .scheme .hljs-keyword, 84 | .tex .hljs-special, 85 | .hljs-prompt { 86 | color: #990073; 87 | } 88 | 89 | .hljs-preprocessor, 90 | .hljs-pragma, 91 | .hljs-pi, 92 | .hljs-doctype, 93 | .hljs-shebang, 94 | .hljs-cdata { 95 | color: #999; 96 | font-weight: bold; 97 | } 98 | 99 | .hljs-deletion { 100 | background: #fdd; 101 | } 102 | 103 | .hljs-addition { 104 | background: #dfd; 105 | } 106 | 107 | .diff .hljs-change { 108 | background: #0086b3; 109 | } 110 | 111 | .hljs-chunk { 112 | color: #aaa; 113 | } 114 | -------------------------------------------------------------------------------- /server/posts/2015-11-24__welcome-to-our-blog/content.md: -------------------------------------------------------------------------------- 1 | You've stumbled upon the official Grommet blog. Congratulations and welcome. 2 | 3 | I'm Bryan Jacquot, HPE Worldwide User Experience Architect. As part of my job, I am lucky enough to lead the Grommet team. 4 | 5 | Since you’re here, you are probably aware Grommet was officially unveiled back in June 2015. We are really excited about the cool stuff we’ve seen accomplished in the short time Grommet has been available. We are confident it is the most advanced UX framework available for enterprise app designers and developers. We hope to make this blog a place for current and aspiring Grommet users to become better informed about the product they use (or will use) and its capabilities. In an effort to keep you in the know, here is a sampling of the topics we’ll be covering in the weeks and months ahead: 6 | 7 | * **Version Updates**: Never ones to sit on our hands, we're constantly tweaking and improving Grommet to make it an even better experience for our users. In the past week, the Grommet team and community of designers and developers made 62 commits. We mean it when we say we're investing big and moving fast. We'll keep you up to date when we make changes and walk you through what's new and improved. 8 | 9 | * **Grommet in the wild**: As the new kids on the UX block, we're constantly spreading the word about Grommet. We're hitting up Twitter chats, conferences, meetups and everything in between, and we'll give you a peek into our appearances. 10 | 11 | * **How to use Grommet**: Realizing most of you reading this blog are will just be getting your feet wet with Grommet, we'll be posting tips and tricks, as well as how-to guides for getting the most out of your experience. 12 | 13 | * **Team Grommet interviews**: While sharing news you can use about Grommet, we'll also introduce you to the people whose passion for a better UX/UI enterprise experience brought the framework to life. 14 | 15 | * **Designer and developer interviews**: We'll also be looking outside our growing Grommet community to talk with prominent designers and developers who will share how they work and provide helpful insights into what makes them tick. 16 | 17 | We look forward to making this blog as informative and useful as possible and look forward to your feedback. What else would you like to hear? Keep an eye on this space to see what we're up to. -------------------------------------------------------------------------------- /server/posts/2016-04-18__the-great-grommet-podcast-episode-four-an-interview-with-digital-accessibility-pro-jennison-asuncion/content.md: -------------------------------------------------------------------------------- 1 | In episode 4 of the Great Grommet podcast, Alan Souza and I were joined by digital accessibility pro Jennison Asuncion, who leads accessibility efforts at LinkedIn. We discuss the the overall state of accessibility and Jennison, as a blind user himself, shares tips for making your digital applications more accessible. 2 | 3 | 4 | 5 | Here’s an overview of the topics discussed in this episode: 6 | 7 | * **0:00** — Grommet updates from Chris Carlozzi 8 | * **4:00** — Meet Jennison Asuncion 9 | * **4:53** — An overview of the CSUN Annual International Technology and Persons with Disabilities Conference 10 | * **5:30** — Discussion on issues with navigating the web for a blind user 11 | * **8:00** — Twitter’s new feature for accessibility: alternative access 12 | * **9:00** — Jennison’s background in digital accessibility 13 | * **10:16** — Jennison’s advice for those getting into digital accessibility 14 | * **12:00** — Examples of how Jennison has educated others on accessibility 15 | * **12:28** — Global Accessibility Awareness Day — May 19 16 | * **16:30** — Recommendations for tools to use for testing website accessibility 17 | * **21:03** — Discussing why is it important for enterprise apps to be accessible 18 | * **24:00** — Recommending blogs that talk about accessibility 19 | * **24:50** — Predicting where accessibility will be in 5 to 10 years 20 | 21 | A full list of links mentioned in the podcast, including Twitter handles, accessibility meetups, event opportunities and apps, is located on [the SoundCloud page](https://soundcloud.com/grommetux/episode-4-interview-with-digital-accessibility-pro-jennison-asuncion). 22 | 23 | We’d like to thank Jennison for joining us and hope you’ve enjoyed this newest podcast. 24 | 25 | As always, be sure to leave us feedback and suggestions on what else you’d like to hear about in the comments below. 26 | 27 | Special thanks to [@sogami](https://twitter.com/sogami) for the podcast intro and [Bensound.com](http://www.bensound.com/) for the music. 28 | -------------------------------------------------------------------------------- /src/js/components/Footer.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | import React, { Component } from 'react'; 4 | 5 | import Anchor from 'grommet/components/Anchor'; 6 | import Paragraph from 'grommet/components/Paragraph'; 7 | import Box from 'grommet/components/Box'; 8 | import Footer from 'grommet/components/Footer'; 9 | import Menu from 'grommet/components/Menu'; 10 | import SocialSlack from 'grommet/components/icons/base/SocialSlack'; 11 | import SocialTwitter from 'grommet/components/icons/base/SocialTwitter'; 12 | import SocialFacebook from 'grommet/components/icons/base/SocialFacebook'; 13 | import SocialVimeo from 'grommet/components/icons/base/SocialVimeo'; 14 | 15 | export default class BlogFooter extends Component { 16 | render () { 17 | let socialSlack = ( 18 | 20 | ); 21 | 22 | let socialTwitter = ( 23 | 25 | ); 26 | 27 | let socialFacebook = ( 28 | 30 | ); 31 | 32 | let socialVimeo = ( 33 | 34 | ); 35 | 36 | return ( 37 | 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /server/posts/2015-12-07__reflections-on-grommet-at-hpe-discover-2015-in-london/content.md: -------------------------------------------------------------------------------- 1 | Last week we spent three days evangelizing Grommet at Hewlett Packard Enterprise (HPE) Discover in London. Given it's only been about six months since Grommet was publicly unveiled, our experience last week was highly encouraging. 2 | 3 | When Grommet was first announced at HP Discover Las Vegas in June 2015, our booth traffic was fairly light. Most people who came by were naturally unfamiliar with the platform and were surprised HP was doing something like Grommet. This time around in London, we talked with a great many more people. There were still some quizzical approaches but there was also much more interest and visible enthusiasm given we’ve been out in the wild for a bit now. 4 | 5 | ![Chris talking with HPE Discover attendees.](IMG_1228.jpg) 6 | 7 | HPE customers shared with us how Grommet could improve their user's experiences and shorten application development time. Some had limited design resources and were hopeful Grommet would elevate the design of their applications. 8 | 9 | Internal HPE teams also demonstrated an encouraging level of excitement, and there were already a handful of products with Grommet-based demos at the event. We even had people came by just to tell us they or someone on their team had successfully started working with Grommet and were happy with the results. What really surprised us was the level of hopefulness that the entire company would finally be moving toward a more consistent user interface experience. While this has always been an aspect of Grommet, it was encouraging to see it taking shape in this way. 10 | 11 | ![Demoing Grommet](IMG_1218-225x300.jpg) 12 | 13 | We came away from the show wanting to provide even more help for current and future Grommet users: example applications and templates; on-boarding paths; and tools to help teams create new themes and provide Grommet documentation to their developers using their own theme. We also want to improve our design resources to help teams get beyond thinking about just re-skinning and instead ask themselves what experiences they could be giving their users. Look for more sample applications coming soon on [grommet.io](https://grommet.github.io)! 14 | 15 | We're already contemplating the next Discover event in Las Vegas in 2016 where we hope to have an expanded presence with an interactive device wall. 16 | 17 | Thanks to everyone who came by and to everyone helping to grow the Grommet community. We came away inspired by what we're all working on and we hope you are too. 18 | -------------------------------------------------------------------------------- /server/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | <%- blogTitle %> 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | <%- asyncData %> 33 | 34 | 35 |
<%- appBody %>
36 | 37 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /gulpfile.babel.js: -------------------------------------------------------------------------------- 1 | import yargs from 'yargs'; 2 | const argv = yargs.argv; 3 | import del from 'del'; 4 | import git from 'gulp-git'; 5 | import gulp from 'gulp'; 6 | import mkdirp from 'mkdirp'; 7 | import grommetToolbox, {getOptions} from 'grommet-toolbox'; 8 | 9 | const opts = getOptions(); 10 | 11 | gulp.task('set-webpack-alias', () => { 12 | if (opts.alias && argv.useAlias) { 13 | console.log('Using local alias for development.'); 14 | opts.webpack.resolve.alias = opts.alias; 15 | } 16 | }); 17 | 18 | gulp.task('release:createTmp', (done) => { 19 | del.sync(['./tmp']); 20 | mkdirp('./tmp', (err) => { 21 | if (err) { 22 | throw err; 23 | } 24 | done(); 25 | }); 26 | }); 27 | 28 | gulp.task('release:heroku', ['dist', 'release:createTmp'], (done) => { 29 | if (process.env.CI) { 30 | git.clone('https://' + process.env.GH_TOKEN + '@github.com/grommet/grommet-blog.git', 31 | { 32 | cwd: './tmp/' 33 | }, 34 | (err) => { 35 | if (err) { 36 | throw err; 37 | } 38 | 39 | process.chdir('./tmp/grommet-blog'); 40 | git.checkout('heroku', (err) => { 41 | if (err) { 42 | throw err; 43 | } 44 | 45 | del.sync(['./**/*']); 46 | 47 | gulp.src(['../../**']) 48 | .pipe(gulp.dest('./')).on('end', () => { 49 | git.status({ 50 | args: '--porcelain' 51 | }, (err, stdout) => { 52 | if (err) { 53 | throw err; 54 | } 55 | 56 | if (stdout && stdout !== '') { 57 | gulp.src('./') 58 | .pipe(git.add({ 59 | args: '--all' 60 | })) 61 | .pipe(git.commit('Heroku version update.')).on('end', () => { 62 | git.push('origin', 'heroku', { quiet: true }, (err) => { 63 | if (err) { 64 | throw err; 65 | } 66 | 67 | process.chdir(__dirname); 68 | done(); 69 | }); 70 | }); 71 | } else { 72 | console.log('No difference since last commit, skipping heroku release.'); 73 | 74 | process.chdir(__dirname); 75 | done(); 76 | } 77 | }); 78 | }); 79 | }); 80 | } 81 | ); 82 | } else { 83 | console.warn('Skipping release. Release:heroku task should be executed by CI only.'); 84 | } 85 | }); 86 | 87 | grommetToolbox(gulp); 88 | -------------------------------------------------------------------------------- /src/js/components/manage/ManageEditPost.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. 2 | 3 | import React, { Component } from 'react'; 4 | 5 | import PostForm from './PostForm'; 6 | import ManageHeader from './Header'; 7 | 8 | import store from '../../store'; 9 | import history from '../../RouteHistory'; 10 | import Error from '../Error'; 11 | import Loading from '../Loading'; 12 | 13 | export default class ManageEditPost extends Component { 14 | 15 | /** 16 | * used by the server to achieve isomorphic with async data. 17 | * This function must return a promise! 18 | * See /server/blog.js. 19 | */ 20 | static fetchData (location, params, appContext) { 21 | store.addContext(appContext); 22 | return store.getPost(params.splat, true); 23 | } 24 | 25 | constructor () { 26 | super(); 27 | 28 | this._onEditPost = this._onEditPost.bind(this); 29 | this._onEditPostSucceed = this._onEditPostSucceed.bind(this); 30 | this._onEditPostFailed = this._onEditPostFailed.bind(this); 31 | this._onGetPostSucceed = this._onGetPostSucceed.bind(this); 32 | this._onGetPostFailed = this._onGetPostFailed.bind(this); 33 | 34 | this.state = { 35 | error: undefined, 36 | loading: true 37 | }; 38 | } 39 | 40 | componentDidMount () { 41 | store.getPost(this.props.params.splat, true).then( 42 | this._onGetPostSucceed, this._onGetPostFailed 43 | ); 44 | } 45 | 46 | _onGetPostSucceed (post) { 47 | this.setState({ 48 | post: post 49 | }); 50 | } 51 | 52 | _onGetPostFailed () { 53 | this.setState({ 54 | error: 'Could not retrieve post, please try again.' 55 | }); 56 | } 57 | 58 | _onEditPost (post) { 59 | store.editPost(post).then( 60 | this._onEditPostSucceed, this._onEditPostFailed 61 | ); 62 | } 63 | 64 | _onEditPostSucceed () { 65 | history.push('/manage'); 66 | } 67 | 68 | _onEditPostFailed () { 69 | this.setState({ 70 | error: 'Could not edit post, please try again.' 71 | }); 72 | } 73 | 74 | render () { 75 | 76 | this.post = this.state.post; 77 | this.loading = this.state.loading; 78 | if (store.useContext() && this.context.asyncData) { 79 | this.loading = false; 80 | this.post = this.context.post; 81 | } 82 | 83 | let editPostNode; 84 | if (this.post) { 85 | editPostNode = ( 86 | 89 | ); 90 | } else if (this.state.error) { 91 | editPostNode = ( 92 | 93 | ); 94 | } else if (!this.loading) { 95 | editPostNode = ( 96 |

No post has been found.

97 | ); 98 | } else { 99 | editPostNode = ( 100 |
101 | 102 | 103 |
104 | ); 105 | } 106 | 107 | return ( 108 |
109 | {editPostNode} 110 |
111 | ); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /server/posts/2015-12-10__how-to-contribute-to-grommet-on-github/content.md: -------------------------------------------------------------------------------- 1 | Grommet was built as a fully open-source project and in the spirit of openness, it is currently hosted on GitHub. For those unfamiliar with GitHub, it is the world's largest open-source community and a powerful tool for collaboration. 2 | 3 | We want Grommet to grow and improve with the help of our community. There is a learning curve to get up to speed with the GitHub workflow and we don't want that to be a barrier for you in sharing your valuable contributions. By following the steps in this post, we hope you will understand everything that is required to make your first contribution to Grommet. 4 | 5 | Steps: 6 | 7 | 1. **Create a GitHub account if you don’t have one**: Head to https://github.com/join and fill out the form with your account details. 8 | 9 | 2. **Fork Grommet into your personal account**: Creating a fork is a way to produce a copy of someone else’s project. All your contributions should be done in your local fork. When you feel your contribution is finished, you need to send a Pull Request. Head to https://github.com/grommet/grommet and click the fork button as described in Figure 1. 10 | 11 | ![Figure 1](fork.png) 12 | 13 | 3. **Clone your forked version of Grommet**: Open a terminal window (or use a Git GUI tool of your choice) and run the following command: 14 | 15 | ```bash 16 | git clone https://github.com/${username}/grommet.git 17 | ``` 18 | 19 | Replace `${username}` with your Github id. 20 | 21 | 4. **Install Grommet in your local environment**: Read the [Building Grommet wiki page](https://github.com/grommet/grommet/wiki/Building-Grommet) to learn how to install your fork locally. 22 | 23 | 5. **Add a change to your fork**: Now that you have successfully installed Grommet, you can add a change in your local fork and push that to your GitHub. We recommend that you create a Git branch before doing any changes in your local fork. It's a good practice to keep your master branch clean as it makes it easier to keep your local fork always in sync with the main Grommet repository. [Check this blog post](https://gun.io/blog/how-to-github-fork-branch-and-pull-request/) if you want to understand more about forking best practices. The general commands you need to execute are described below: 24 | 25 | ```bash 26 | cd grommet 27 | git checkout -b ${SHORT_CHANGE_TITLE} 28 | git add . 29 | git commit -m "${CHANGE_DESCRIPTION}" 30 | git push origin ${SHORT_CHANGE_TITLE} 31 | ``` 32 | Replace `${SHORT_CHANGE_TITLE}` with a clear title of what your change is about. Also, replace `${CHANGE_DESCRIPTION}` with more descriptive information about the contribution. 33 | 34 | 6. **Create a Pull Request**: As soon as your branch is pushed from your local branch to your GitHub fork, you will be able to see a "Compare & Pull Request" button as shown in Figure 2. 35 | 36 | ![Figure 2](compare_and_pr.png) 37 | 38 | We have provided some [helpful guidelines for contributing to Grommet](https://github.com/grommet/grommet/blob/master/CONTRIBUTING.md), so please make sure to check those out before making a Pull Request. 39 | 40 | 7. **Wait for feedback**: After your Pull Request is submitted, a member of the core Grommet team will review your contribution. If everything looks great, it will be merged with Grommet and your legend will grow.It's possible the Grommet team member reviewing your Pull Request will have feedback and ask that you make some changes. We'll cover that scenario in a separate blog post in the near future. We hope you find the information here useful. Please leave comment if you have any questions! -------------------------------------------------------------------------------- /src/js/components/Post.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | import React, { Component, PropTypes } from 'react'; 4 | import DisqusThread from 'react-disqus-thread'; 5 | 6 | import Article from 'grommet/components/Article'; 7 | import Box from 'grommet/components/Box'; 8 | 9 | import BlogHeader from './Header'; 10 | import Footer from './Footer'; 11 | import Loading from './Loading'; 12 | import Error from './Error'; 13 | import PostBody from './PostBody'; 14 | 15 | import store from '../store'; 16 | 17 | import { setDocumentTitle } from '../utils/blog'; 18 | 19 | export default class Post extends Component { 20 | 21 | /** 22 | * used by the server to achieve isomorphic with async data. 23 | * This function must return a promise! 24 | * See /server/blog.js. 25 | */ 26 | static fetchData (location, params, appContext) { 27 | store.addContext(appContext); 28 | return store.getPost(params.splat); 29 | } 30 | 31 | constructor () { 32 | super(); 33 | 34 | this._onPostReceived = this._onPostReceived.bind(this); 35 | this._onPostFailed = this._onPostFailed.bind(this); 36 | 37 | this.state = { 38 | post: undefined, 39 | loading: true 40 | }; 41 | } 42 | 43 | componentDidMount () { 44 | store.getPost(this.props.params.splat).then( 45 | this._onPostReceived, this._onPostFailed 46 | ); 47 | } 48 | 49 | componentWillReceiveProps () { 50 | store.getPost(this.props.params.splat).then( 51 | this._onPostReceived, this._onPostFailed 52 | ); 53 | } 54 | 55 | _onPostReceived (post) { 56 | if (post) { 57 | setDocumentTitle(post.title); 58 | this.setState({ post: post, loading: false }); 59 | } else { 60 | this.setState({ post: post, loading: false }); 61 | } 62 | } 63 | 64 | _onPostFailed () { 65 | this.setState({ 66 | post: undefined, 67 | loading: false, 68 | error: 'Could not load post. Make sure you have internet connection and try again.' 69 | }); 70 | } 71 | 72 | _renderComment () { 73 | return ( 74 | 75 | 77 | 78 | ); 79 | } 80 | 81 | render () { 82 | 83 | this.post = this.state.post; 84 | this.loading = this.state.loading; 85 | if (store.useContext() && this.context.asyncData) { 86 | this.loading = false; 87 | this.post = this.context.asyncData; 88 | } 89 | 90 | let postNode; 91 | if (this.post) { 92 | postNode = ( 93 |
94 | 95 | 96 | 97 | {this._renderComment()} 98 |
99 |
100 | ); 101 | } else if (this.state.error) { 102 | postNode = ( 103 | 104 | ); 105 | } else if (!this.loading) { 106 | postNode = ( 107 | 108 |

No post has been found.

109 |
110 | ); 111 | } else { 112 | postNode = ( 113 | 114 | ); 115 | } 116 | 117 | return ( 118 |
119 | 120 | {postNode} 121 |
122 | ); 123 | } 124 | }; 125 | 126 | Post.propTypes = { 127 | params: PropTypes.object 128 | }; 129 | 130 | Post.contextTypes = { 131 | asyncData: PropTypes.any 132 | }; 133 | -------------------------------------------------------------------------------- /server/posts/2016-04-08__top-5-rules-for-giving-enterprise-apps-a-consumer-grade-ux/content.md: -------------------------------------------------------------------------------- 1 | > This article was originally posted on [ProgrammableWeb](http://www.programmableweb.com/news/top-5-rules-giving-enterprise-apps-consumer-grade-ux/analysis/2016/01/26). 2 | 3 | Software users in the consumer market have come to expect what is referred to as the “consumer-grade user experience.” It usually goes something like this: a consumer downloads an app from an app store and if it doesn’t meet their needs, they delete it and move on to the next one. Consumers expect the app to get them started quickly through an inviting and straightforward introductory experience. They do not attend training or read manuals and use applications by choice, not because they are required to do so. 4 | 5 | Generally speaking, the traditional enterprise user experience is the antithesis of the consumer grade user experience. Many enterprise applications were not designed with simplicity, clarity and ease-of-use in mind. Some were not even designed to scale according to the demands of today’s enterprises. 6 | 7 | Enterprise applications often rely on their users to be highly skilled, having undergone extensive training and earning certifications just to use them effectively. There are “quick start” guides that are anything but quick, voluminous release notes and manuals describing every nuance of an application’s expected and unexpected behaviors. 8 | 9 | Users of enterprise applications begrudgingly use them out of duty, not desire. A consumer-grade user experience for the enterprise is the delivery of applications to the enterprise market with enterprise capabilities and a consumer-grade user experience. Such solutions provide a competitive advantage, a strong buying preference and a loyal customer base. 10 | 11 | The ideal consumer-grade user experience needs to have the following five characteristics. Without all of these, it would be difficult for an application to be considered consumer grade: 12 | 13 | * **Simple** – Mobile applications have proven simple designs can be powerful. Consumer-grade experiences present aggregated information and actions necessary for the given task along with appropriate navigation to details. Consumer-grade applications do not overload the user by expecting them to find the salient information among troves of data. 14 | 15 | * **Visually appealing** – This is critical for a consumer-grade user experience. Users are more relaxed, comfortable, confident and capable when using a product that has pleasing aesthetics. 16 | 17 | * **Naturally intuitive** – Users quickly recognize familiar patterns and become immediately successful if they’ve encountered a pattern previously. Enabling users to transfer their knowledge from other applications decreases cognitive load and increases confidence. 18 | 19 | * **Responsive** – User mobility demands applications work on any screen ranging from phone to tablet to desktop to big screen. Responsive applications are composed of responsive components, layouts and patterns which operate naturally on any device at any screen size. Consumer-grade applications do not rely on zooming and panning for readability and navigation. 20 | 21 | * **Accessible** – All users, including those with disabilities, should have a pleasing experience. 22 | 23 | In addition to the above application characteristics, a solution’s user experience extends beyond an application’s user interface. The out-of-box ceremony, physical deployment, installation, registration, upgrade process, security, support and end-of-life cycle are all critically important to delivering a consumer-grade user experience for the enterprise. 24 | 25 | Enterprise users deserve a great experience; the type of experience they’ve now come to expect from applications they use every day outside their jobs. The modern Web, social media, and mobile platforms have changed their expectations. -------------------------------------------------------------------------------- /server/posts/2016-02-12__why-you-should-be-friends-with-your-style-guide/content.md: -------------------------------------------------------------------------------- 1 | You learn them and you love them. Most designers would say that sarcastically but style guides actually promote creativity rather than stifle it. 2 | 3 | [Grommet’s open source style guide](https://github.com/grommet/grommet-design/raw/master/grommet/grommet-sticker-sheet-apps-general-0-2.sketch), built using [Sketch](http://bohemiancoding.com/sketch/), creates a baseline for designers (and ambidextrous developers) to mold their ideas and applications. By referencing the styles, we not only provide consistency in every app, but we also supply flexibility to create a cohesive brand identity. Some designers may call these guides “constraints,” but Grommet’s guidelines are meant to do just that — guide. If you look closely, you’ll notice each element is crafted to work together seamlessly. That principle is what makes our styles flexible and also results in effortless theming in Grommet. 4 | 5 | Carrie Cousins from [Design Shack](http://designshack.net/articles/graphics/designing-with-constraints-thinking-inside-the-box/) reminds us that thinking inside the box may be a key “to consistency that helps brands establish visual identity and guide voice.” Learning someone else’s design process can profoundly influence your design, regardless of the style. 6 | 7 | Below I’ll walk through some of Grommet’s “keys to consistency” in our open source style guide. 8 | 9 | ### Text Styling 10 | 11 | “Is black text actually black?” “Why do you use dark grey (#333) instead of black (#000) for your Primary text color?” If you look at dark items in nature, there are not many objects that are 100% black. Your shadow, tires on a car, or the night sky, none are pure black. Forcing an app to incorporate too much black can be overwhelming since it’s not “natural” to the human eye and can make it harder to read. \[1\] 12 | 13 | ### Color Palette 14 | 15 | The Grommet purple provides uniqueness amongst its sister frameworks, since we have integrated what is normally a secondary color into our “Call to Action.” Purple gives a great mix between its parent colors, red and blue, by incorporating red’s stimulation and blue’s calm. Purple is said to have “the power to uplift, calm nerves and encourage creativity.” \[2\] This makes purple a universal, all-inclusive color — and it’s not the common-played blue! 16 | 17 | ### Buttons 18 | 19 | Grommet’s buttons have rounded corners to allow for quick visual processing of the button and the text inside. Rounded containers have corners that point inward toward the middle of the button, putting the user’s focus on the text inside. Sharp corners point outward, putting less focus on the inside text and forcing the user to process the information longer.\[3\] Since buttons are fundamental, regularly occurring objects in apps, they need to be easily processed by the user’s eye. 20 | 21 | ### Conclusion 22 | 23 | We hope the Grommet open source style guide will allow you to kick off your next project knowing we have already infused many design principles in the guidelines by default. By building on to our foundation, you can ensure app consistency and the design freedom to focus on what your business needs. 24 | 25 | And remember, you can always [contribute](https://github.com/grommet/grommet-design)! Let us know what you think in the comments. 26 | 27 | ### Footnotes 28 | 29 | 1. “Design Tip: Never Use Black.” Ian Storm Taylor. N.p., n.d. Web. 12 Jan. 2016. 30 | http://ianstormtaylor.com/design-tip-never-use-black/ 31 | 32 | 2. “Psychology of the Color Purple and What It Means for Your Business | Fatrabbit CREATIVE.” Website Design | Graphic Design Agency in Morris County NJ | Fatrabbit CREATIVE. N.p., n.d. Web. 12 Jan. 2016. 33 | http://www.fatrabbitcreative.com/blog/psychology_of_the_color_purple_and_what_it_means_for_your_business 34 | 35 | 3. “Why Rounded Corners Are Easier on the Eyes – UX Movement.” UX Movement – Articles on User Experience Design. N.p., n.d. Web. 12 Jan. 2016. 36 | http://uxmovement.com/thinking/why-rounded-corners-are-easier-on-the-eyes/ -------------------------------------------------------------------------------- /.scss-lint.yml: -------------------------------------------------------------------------------- 1 | # Default application configuration that all configurations inherit from. 2 | 3 | scss_files: "**/*.scss" 4 | 5 | linters: 6 | BangFormat: 7 | enabled: true 8 | space_before_bang: true 9 | space_after_bang: false 10 | 11 | BorderZero: 12 | enabled: true 13 | convention: none # or `zero` 14 | 15 | ColorKeyword: 16 | enabled: true 17 | 18 | ColorVariable: 19 | enabled: false 20 | 21 | Comment: 22 | enabled: true 23 | 24 | DebugStatement: 25 | enabled: true 26 | 27 | DeclarationOrder: 28 | enabled: false 29 | 30 | DuplicateProperty: 31 | enabled: true 32 | 33 | ElsePlacement: 34 | enabled: true 35 | style: same_line # or 'new_line' 36 | 37 | EmptyLineBetweenBlocks: 38 | enabled: true 39 | ignore_single_line_blocks: true 40 | 41 | EmptyRule: 42 | enabled: true 43 | 44 | FinalNewline: 45 | enabled: true 46 | present: true 47 | 48 | HexLength: 49 | enabled: false 50 | style: short # or 'long' 51 | 52 | HexNotation: 53 | enabled: false 54 | style: lowercase # or 'uppercase' 55 | 56 | HexValidation: 57 | enabled: true 58 | 59 | IdSelector: 60 | enabled: false 61 | 62 | ImportantRule: 63 | enabled: true 64 | 65 | ImportPath: 66 | enabled: true 67 | leading_underscore: false 68 | filename_extension: false 69 | 70 | Indentation: 71 | enabled: false 72 | allow_non_nested_indentation: false 73 | character: tab # or 'tab' 74 | width: 2 75 | 76 | LeadingZero: 77 | enabled: true 78 | style: include_zero # or 'exclude_zero' 79 | 80 | MergeableSelector: 81 | enabled: true 82 | force_nesting: true 83 | 84 | NameFormat: 85 | enabled: true 86 | allow_leading_underscore: true 87 | convention: hyphenated_lowercase # or 'BEM', or a regex pattern 88 | 89 | NestingDepth: 90 | enabled: false 91 | max_depth: 6 92 | 93 | PlaceholderInExtend: 94 | enabled: true 95 | 96 | PropertyCount: 97 | enabled: false 98 | include_nested: false 99 | max_properties: 10 100 | 101 | PropertySortOrder: 102 | enabled: false 103 | 104 | PropertySpelling: 105 | enabled: true 106 | extra_properties: ['animate'] 107 | 108 | QualifyingElement: 109 | enabled: true 110 | allow_element_with_attribute: true 111 | allow_element_with_class: true 112 | allow_element_with_id: false 113 | 114 | SelectorDepth: 115 | enabled: false 116 | max_depth: 4 117 | 118 | SelectorFormat: 119 | enabled: true 120 | convention: hyphenated_BEM # or 'BEM', or 'hyphenated_BEM', or 'snake_case', or 'camel_case', or a regex pattern 121 | 122 | Shorthand: 123 | enabled: true 124 | 125 | SingleLinePerProperty: 126 | enabled: true 127 | allow_single_line_rule_sets: true 128 | 129 | SingleLinePerSelector: 130 | enabled: true 131 | 132 | SpaceAfterComma: 133 | enabled: true 134 | 135 | SpaceAfterPropertyColon: 136 | enabled: true 137 | style: at_least_one_space # or 'no_space', or 'on_space', or 'at_least_one_space', or 'aligned' 138 | 139 | SpaceAfterPropertyName: 140 | enabled: true 141 | 142 | SpaceBeforeBrace: 143 | enabled: true 144 | style: space # or 'new_line' 145 | allow_single_line_padding: false 146 | 147 | SpaceBetweenParens: 148 | enabled: true 149 | spaces: 0 150 | 151 | StringQuotes: 152 | enabled: false 153 | style: single_quotes # or double_quotes 154 | 155 | TrailingSemicolon: 156 | enabled: true 157 | 158 | TrailingZero: 159 | enabled: false 160 | 161 | UnnecessaryMantissa: 162 | enabled: true 163 | 164 | UnnecessaryParentReference: 165 | enabled: true 166 | 167 | UrlFormat: 168 | enabled: false 169 | 170 | UrlQuotes: 171 | enabled: false 172 | 173 | VariableForProperty: 174 | enabled: false 175 | properties: [] 176 | 177 | VendorPrefix: 178 | enabled: false 179 | 180 | ZeroUnit: 181 | enabled: false 182 | 183 | Compass::*: 184 | enabled: false 185 | -------------------------------------------------------------------------------- /src/js/Home.js: -------------------------------------------------------------------------------- 1 | // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company, L.P. 2 | 3 | import React, { Component, PropTypes } from 'react'; 4 | import fecha from 'fecha'; 5 | import { Link } from 'react-router'; 6 | 7 | import Article from 'grommet/components/Article'; 8 | import Box from 'grommet/components/Box'; 9 | import Heading from 'grommet/components/Heading'; 10 | import Section from 'grommet/components/Section'; 11 | 12 | import store from './store'; 13 | import Header from './components/Header'; 14 | import Footer from './components/Footer'; 15 | import Loading from './components/Loading'; 16 | import Error from './components/Error'; 17 | 18 | import { setDocumentTitle } from './utils/blog'; 19 | 20 | const HomeSection = (props) => { 21 | return ( 22 |
23 | 26 | {props.children} 27 | 28 |
29 | ); 30 | }; 31 | 32 | export default class Home extends Component { 33 | 34 | /** 35 | * used by the server to achieve isomorphic with async data. 36 | * This function must return a promise! 37 | * See /server/blog.js. 38 | */ 39 | static fetchData (location, params, appContext) { 40 | store.addContext(appContext); 41 | return store.getPosts(); 42 | } 43 | 44 | constructor () { 45 | super(); 46 | 47 | this._onPostsReceived = this._onPostsReceived.bind(this); 48 | this._onPostsFailed = this._onPostsFailed.bind(this); 49 | 50 | this.state = { 51 | posts: [], 52 | loading: true 53 | }; 54 | } 55 | 56 | componentDidMount () { 57 | setDocumentTitle(); 58 | store.getPosts().then(this._onPostsReceived, this._onPostsFailed); 59 | } 60 | 61 | componentWillReceiveProps () { 62 | store.getPosts().then(this._onPostsReceived, this._onPostsFailed); 63 | } 64 | 65 | _onPostsReceived (posts) { 66 | this.setState({ posts: posts, loading: false }); 67 | } 68 | 69 | _onPostsFailed () { 70 | this.setState({ 71 | posts: [], 72 | loading: false, 73 | error: 'Could not load posts. Make sure you have internet connection and try again.' 74 | }); 75 | } 76 | 77 | render () { 78 | 79 | this.posts = this.state.posts; 80 | this.loading = this.state.loading; 81 | if (store.useContext() && this.context.asyncData) { 82 | this.loading = false; 83 | this.posts = this.context.asyncData; 84 | } 85 | 86 | let postsNode; 87 | let footerNode; 88 | if (this.posts.length > 0) { 89 | footerNode = ( 90 |