aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBastien Wirtz <bastien.wirtz@gmail.com>2019-02-19 22:20:46 -0800
committerBastien Wirtz <bastien.wirtz@gmail.com>2019-02-19 22:20:46 -0800
commit4877ec98e668b1741d7a2a4d3e4a177ec495db39 (patch)
tree39bc5d0bb4065ee2d96aa53501d51b1f3729c794
parent9baec9aec294656fb632123906b4ac6a712267ba (diff)
downloadhomer-4877ec98e668b1741d7a2a4d3e4a177ec495db39.tar.gz
homer-4877ec98e668b1741d7a2a4d3e4a177ec495db39.tar.zst
homer-4877ec98e668b1741d7a2a4d3e4a177ec495db39.zip
Vertical layout support
-rw-r--r--app.css21
-rw-r--r--app.js29
-rw-r--r--app.scss31
-rw-r--r--index.html59
4 files changed, 100 insertions, 40 deletions
diff --git a/app.css b/app.css
index 60d2762..846b54b 100644
--- a/app.css
+++ b/app.css
@@ -11,7 +11,7 @@ body {
11 font-size: 2rem; } 11 font-size: 2rem; }
12 body h2 { 12 body h2 {
13 font-size: 1.7rem; 13 font-size: 1.7rem;
14 margin-top: 3rem; 14 margin-top: 2rem;
15 margin-bottom: 1rem; } 15 margin-bottom: 1rem; }
16 body h2 .fas, body h2 .fab, body h2 .far { 16 body h2 .fas, body h2 .fab, body h2 .far {
17 margin-right: 10px; } 17 margin-right: 10px; }
@@ -92,6 +92,8 @@ body {
92 border: none; 92 border: none;
93 box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); 93 box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1);
94 transition: cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; } 94 transition: cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; }
95 body .card a {
96 outline: none; }
95 body .card:hover { 97 body .card:hover {
96 background-color: #FFFFFF; 98 background-color: #FFFFFF;
97 transform: translate(0, -3px); } 99 transform: translate(0, -3px); }
@@ -102,17 +104,26 @@ body {
102 body .card-content { 104 body .card-content {
103 height: 85px; 105 height: 85px;
104 padding: 1.3rem; } 106 padding: 1.3rem; }
107 body .layout-vertical .card {
108 border-radius: 0; }
109 body .layout-vertical .column div:first-of-type .card {
110 border-radius: 5px 5px 0 0; }
111 body .layout-vertical .column div:last-child .card {
112 border-radius: 0 0 5px 5px; }
105 body .footer { 113 body .footer {
106 position: fixed; 114 position: fixed;
107 left: 0; 115 left: 0;
108 right: 0; 116 right: 0;
109 bottom: 0; 117 bottom: 0;
110 padding: 1rem 0.5rem; 118 padding: 0.5rem;
111 text-align: left; 119 text-align: left;
112 background-color: #fafafa; 120 background-color: #fafafa;
113 border-top: 1px solid #F5F5F5; } 121 border-top: 1px solid #F5F5F5;
122 color: #676767;
123 font-size: 0.85rem; }
114 body .search-bar { 124 body .search-bar {
115 position: relative; } 125 position: relative;
126 display: inline-block; }
116 body .search-bar #search { 127 body .search-bar #search {
117 border: none; 128 border: none;
118 background-color: #5f98f6; 129 background-color: #5f98f6;
@@ -137,6 +148,8 @@ body {
137 height: 20px; } 148 height: 20px; }
138 body .search-bar:focus-within .search-label::before { 149 body .search-bar:focus-within .search-label::before {
139 color: #4a4a4a; } 150 color: #4a4a4a; }
151 body .icon-button {
152 display: inline-block; }
140 body .offline-message { 153 body .offline-message {
141 text-align: center; 154 text-align: center;
142 margin: 35px 0; } 155 margin: 35px 0; }
diff --git a/app.js b/app.js
index 6e20ea3..dc8b6cc 100644
--- a/app.js
+++ b/app.js
@@ -4,6 +4,7 @@ const app = new Vue({
4 config: null, 4 config: null,
5 offline: false, 5 offline: false,
6 filter: '', 6 filter: '',
7 vlayout: true
7 }, 8 },
8 created: function () { 9 created: function () {
9 let that = this; 10 let that = this;
@@ -46,6 +47,34 @@ const app = new Vue({
46 } 47 }
47}); 48});
48 49
50Vue.component('service', {
51 props: ['item'],
52 template: `<div>
53 <div class="card">
54 <a :href="item.url">
55 <div class="card-content">
56 <div class="media">
57 <div v-if="item.logo" class="media-left">
58 <figure class="image is-48x48">
59 <img :src="item.logo" />
60 </figure>
61 </div>
62 <div v-if="item.icon" class="media-left">
63 <figure class="image is-48x48">
64 <i style="font-size: 35px" :class="item.icon"></i>
65 </figure>
66 </div>
67 <div class="media-content">
68 <p class="title is-4">{{ item.name }}</p>
69 <p class="subtitle is-6">{{ item.subtitle }}</p>
70 </div>
71 </div>
72 <strong class="tag" v-if="item.tag">#{{ item.tag }}</strong>
73 </div>
74 </a>
75 </div></div>`
76});
77
49if ('serviceWorker' in navigator) { 78if ('serviceWorker' in navigator) {
50 window.addEventListener('load', function () { 79 window.addEventListener('load', function () {
51 navigator.serviceWorker.register('/worker.js'); 80 navigator.serviceWorker.register('/worker.js');
diff --git a/app.scss b/app.scss
index da6271d..ab9a394 100644
--- a/app.scss
+++ b/app.scss
@@ -18,7 +18,7 @@ body {
18 18
19 h2 { 19 h2 {
20 font-size: 1.7rem; 20 font-size: 1.7rem;
21 margin-top: 3rem; 21 margin-top: 2rem;
22 margin-bottom: 1rem; 22 margin-bottom: 1rem;
23 23
24 .fas, .fab, .far { 24 .fas, .fab, .far {
@@ -147,7 +147,11 @@ body {
147 border-radius: 5px; 147 border-radius: 5px;
148 border: none; 148 border: none;
149 box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); 149 box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1);
150 transition: cubic-bezier(0.165, 0.84, 0.44, 1) 300ms 150 transition: cubic-bezier(0.165, 0.84, 0.44, 1) 300ms;
151
152 a {
153 outline: none;
154 }
151 } 155 }
152 156
153 .card:hover { 157 .card:hover {
@@ -166,19 +170,36 @@ body {
166 padding: 1.3rem; 170 padding: 1.3rem;
167 } 171 }
168 172
173 .layout-vertical {
174 .card {
175 border-radius: 0;
176 }
177
178 .column div:first-of-type .card {
179 border-radius: 5px 5px 0 0;
180 }
181
182 .column div:last-child .card {
183 border-radius: 0 0 5px 5px;
184 }
185 }
186
169 .footer { 187 .footer {
170 position: fixed; 188 position: fixed;
171 left: 0; 189 left: 0;
172 right: 0; 190 right: 0;
173 bottom: 0; 191 bottom: 0;
174 padding: 1rem 0.5rem; 192 padding: 0.5rem;
175 text-align: left; 193 text-align: left;
176 background-color: #fafafa; 194 background-color: #fafafa;
177 border-top: 1px solid #F5F5F5; 195 border-top: 1px solid #F5F5F5;
196 color: #676767;
197 font-size: 0.85rem;
178 } 198 }
179 199
180 .search-bar { 200 .search-bar {
181 position: relative; 201 position: relative;
202 display: inline-block;
182 #search { 203 #search {
183 border: none; 204 border: none;
184 background-color: lighten( $secondary-color, 6% ); 205 background-color: lighten( $secondary-color, 6% );
@@ -213,6 +234,10 @@ body {
213 } 234 }
214 } 235 }
215 236
237 .icon-button {
238 display: inline-block;
239 }
240
216 .offline-message { 241 .offline-message {
217 text-align: center; 242 text-align: center;
218 margin: 35px 0; 243 margin: 35px 0;
diff --git a/index.html b/index.html
index 3b83c8e..235afde 100644
--- a/index.html
+++ b/index.html
@@ -7,8 +7,8 @@
7 <meta name="robots" content="noindex"> 7 <meta name="robots" content="noindex">
8 <link rel="icon" type="image/png" href="assets/favicon.png"> 8 <link rel="icon" type="image/png" href="assets/favicon.png">
9 <title>Homer</title> 9 <title>Homer</title>
10 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" 10 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
11 integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous"> 11 integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
12 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css"> 12 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css">
13 <link href="https://fonts.googleapis.com/css?family=Lato|Raleway" rel="stylesheet"> 13 <link href="https://fonts.googleapis.com/css?family=Lato|Raleway" rel="stylesheet">
14 <link rel="stylesheet" href="app.css"> 14 <link rel="stylesheet" href="app.css">
@@ -40,6 +40,8 @@
40 </a> 40 </a>
41 </div> 41 </div>
42 <div class="end"> 42 <div class="end">
43 <a v-on:click="vlayout = !vlayout" class="icon-button navbar-item"><i
44 :class="['fas', vlayout ? 'fa-list' : 'fa-columns']"></i></a>
43 <div class="search-bar"> 45 <div class="search-bar">
44 <label for="search" class="search-label"></label> 46 <label for="search" class="search-label"></label>
45 <input type="text" id="search" v-model="filter" /> 47 <input type="text" id="search" v-model="filter" />
@@ -70,39 +72,30 @@
70 72
71 <h2 v-if="filter"><i class="fas fa-search"></i> Search</h2> 73 <h2 v-if="filter"><i class="fas fa-search"></i> Search</h2>
72 74
73 <div v-for="(group, index) in config.services"> 75 <!-- Horizontal layout -->
74 <h2 v-if="!filter && group.name"><i v-if="group.icon" :class="group.icon"></i><span v-else>#</span> 76 <div v-if="!vlayout || filter" class="columns is-multiline">
75 {{ group.name }}</h2> 77 <template v-for="(group, index) in config.services">
76 <div class="columns is-multiline"> 78 <h2 v-if="!filter && group.name" class="column is-full"><i v-if="group.icon" :class="group.icon"></i><span
77 <div v-for="item in group.items" 79 v-else>#</span>
78 v-if="!filter || (item && (item.name.toLowerCase().includes(filter.toLowerCase()) || (item.tag && item.tag.toLowerCase().includes(filter.toLowerCase()))))" 80 {{ group.name }}</h2>
79 class="column is-one-third-widescreen"> 81 <service v-for="item in group.items" v-bind:item="item" class="column is-one-third-widescreen"
80 <div v-if='item' class="card"> 82 v-if="!filter || (item && (item.name.toLowerCase().includes(filter.toLowerCase()) || (item.tag && item.tag.toLowerCase().includes(filter.toLowerCase()))))">
81 <a :href="item.url"> 83 </service>
82 <div class="card-content"> 84 </template>
83 <div class="media"> 85 </div>
84 <div v-if="item.logo" class="media-left"> 86
85 <figure class="image is-48x48"> 87 <!-- Vertical layout -->
86 <img :src="item.logo" /> 88 <div v-if="!filter && vlayout" class="columns is-multiline layout-vertical">
87 </figure> 89 <div class="column is-one-third-widescreen" v-for="(group, index) in config.services">
88 </div> 90 <h2 v-if="!filter && group.name"><i v-if="group.icon" :class="group.icon"></i><span v-else>#</span>
89 <div v-if="item.icon" class="media-left"> 91 {{ group.name }}</h2>
90 <figure class="image is-48x48"> 92 <service v-for="item in group.items" v-bind:item="item"
91 <i style="font-size: 35px" :class="item.icon"></i> 93 v-if="!filter || (item && (item.name.toLowerCase().includes(filter.toLowerCase()) || (item.tag && item.tag.toLowerCase().includes(filter.toLowerCase()))))">
92 </figure> 94 </service>
93 </div>
94 <div class="media-content">
95 <p class="title is-4">{{ item.name }}</p>
96 <p class="subtitle is-6">{{ item.subtitle }}</p>
97 </div>
98 </div>
99 <strong class="tag" v-if="item.tag">#{{ item.tag }}</strong>
100 </div>
101 </a>
102 </div>
103 </div>
104 </div> 95 </div>
105 </div> 96 </div>
97
98
106 </div> 99 </div>
107 </div> 100 </div>
108 </section> 101 </section>