refactored grid with flex, displayed footer tabs, diplay results, toggle results display
This commit is contained in:
+146
-12
@@ -1,7 +1,7 @@
|
||||
@import './base/reset';
|
||||
@import './base/variables';
|
||||
@import './base/colors';
|
||||
@import './base/grid';
|
||||
@import './base/grid-flex';
|
||||
@import './base/layout';
|
||||
@import './base/fonts';
|
||||
|
||||
@@ -10,6 +10,9 @@ body{
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
#root{
|
||||
}
|
||||
|
||||
header[role="banner"]{
|
||||
div.wrapper{
|
||||
display: grid;
|
||||
@@ -53,14 +56,67 @@ section[role="main-content"]{
|
||||
}
|
||||
footer[role="tools"]{
|
||||
#history{
|
||||
// color: #1a1a1a;
|
||||
background-color: $or;
|
||||
padding:1.2em $side-padding;
|
||||
}
|
||||
#results{
|
||||
// color: #1a1a1a;
|
||||
background-color: $gris;
|
||||
max-height: 50vh;
|
||||
padding:1.2em $side-padding;
|
||||
section.col-1{
|
||||
.results-count{
|
||||
font-size: 0.756em;
|
||||
}
|
||||
}
|
||||
.results-list{
|
||||
overflow-x: hidden;
|
||||
.wrapper{
|
||||
height:100%;
|
||||
overflow-y: auto;
|
||||
width:calc(100% + 1em);
|
||||
padding-right: 1em;
|
||||
>ul{
|
||||
padding:0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
li.result{
|
||||
flex-basis: percentage(2/$default_sum);
|
||||
height: 5.3em;
|
||||
overflow: hidden;
|
||||
margin-bottom: 1em;
|
||||
padding-right: 0.7em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
article.result.item{
|
||||
header{
|
||||
h1{
|
||||
font-size: 0.882em;
|
||||
font-weight: normal;
|
||||
margin:0 0 0.5em 0;
|
||||
}
|
||||
}
|
||||
.extract{
|
||||
p{
|
||||
font-size: 0.882em;
|
||||
margin:0;
|
||||
}
|
||||
code{
|
||||
background-color: lighten(desaturate($rouge,20%), 20%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#footer-bottom{
|
||||
padding:0 $side-padding;
|
||||
background-color: $bleuroi;
|
||||
&>*{
|
||||
// disable grid gap
|
||||
padding-right: 0;
|
||||
}
|
||||
#footer-tabs{
|
||||
ul{
|
||||
padding:0; margin:0;
|
||||
@@ -68,21 +124,25 @@ footer[role="tools"]{
|
||||
flex-direction: column;
|
||||
li{
|
||||
flex: 1 1 auto;
|
||||
box-sizing: border-box;
|
||||
padding:0.3em;
|
||||
margin:0;
|
||||
line-height: 0.6em;
|
||||
height:2em;
|
||||
&.history{
|
||||
.wrapper{
|
||||
box-sizing: border-box;
|
||||
line-height: 0.6em;
|
||||
height:2em;
|
||||
width: calc(100% + $side-padding);
|
||||
margin-left:-$side-padding;
|
||||
padding:0.3em 0.5em 0.3em $side-padding;
|
||||
}
|
||||
&.history .wrapper{
|
||||
background-color: $or;
|
||||
}
|
||||
&.results{
|
||||
&.results .wrapper{
|
||||
background-color: $gris;
|
||||
}
|
||||
span{
|
||||
font-size: 0.693em;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,8 +150,38 @@ footer[role="tools"]{
|
||||
#search{
|
||||
color: #fff;
|
||||
background-color: $bleuroi;
|
||||
label[for="keys"]{
|
||||
display: none;
|
||||
form{
|
||||
padding: 0.7em;
|
||||
label[for="keys"]{
|
||||
display: none;
|
||||
}
|
||||
input[type="text"]{
|
||||
padding:0.3em;
|
||||
font-size: 0.756em;
|
||||
line-height: 1;
|
||||
height:1em;
|
||||
border:none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
// input[type="submit"]{
|
||||
// #submit-search{
|
||||
// border:none;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
span.mdi{
|
||||
display: inline-block;
|
||||
font-size: 1.2em;
|
||||
line-height:1.1;
|
||||
vertical-align:middle;
|
||||
width:1.2em; height:1.2em;
|
||||
border-radius: 0.6em;
|
||||
background-color: #fff;
|
||||
color: $bleuroi;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,5 +190,49 @@ footer[role="tools"]{
|
||||
font-size: 0.756em;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
padding:0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ___
|
||||
// |_ _|__ ___ _ _ ___
|
||||
// | |/ _/ _ \ ' \(_-<
|
||||
// |___\__\___/_||_/__/
|
||||
|
||||
span.mdi-close{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform:rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
span.mdi-loading{
|
||||
animation-name: spin;
|
||||
animation-duration: 2000ms;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
|
||||
|
||||
// _ _ _ _
|
||||
// | |_ _ _ __ _ _ _ __(_) |_(_)___ _ _ ___
|
||||
// | _| '_/ _` | ' \(_-< | _| / _ \ ' \(_-<
|
||||
// \__|_| \__,_|_||_/__/_|\__|_\___/_||_/__/
|
||||
|
||||
.fade-roll-enter-active{
|
||||
transition: all .3s ease-in-out;
|
||||
}
|
||||
.fade-roll-leave-active{
|
||||
transition: all .8s ease;
|
||||
}
|
||||
.fade-roll-enter, .fade-roll-leave-to{
|
||||
opacity:0;
|
||||
// height:1px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// http://www.thesassway.com/intermediate/simple-grid-mixins
|
||||
|
||||
|
||||
@mixin row() {
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: stretch;
|
||||
// &:after{
|
||||
// content:"";
|
||||
// clear:both;
|
||||
// display: block;
|
||||
// }
|
||||
}
|
||||
|
||||
.row{
|
||||
@include row;
|
||||
}
|
||||
.row-rl{
|
||||
@include row;
|
||||
}
|
||||
|
||||
%col-reset {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@mixin col($col, $offset: 0, $sum: $default_sum, $gap: $default_gap, $align: top) {
|
||||
@extend %col-reset;
|
||||
padding-left: $gap*$offset;
|
||||
@if $col == $default_sum {
|
||||
// if last col, then no gap
|
||||
padding-right: 0;
|
||||
}@else{
|
||||
padding-right: $gap;
|
||||
}
|
||||
&:last-child{padding-right: 0;}
|
||||
|
||||
// no offset with flex ??
|
||||
// margin-left: percentage(($col/$sum)*$offset);
|
||||
|
||||
// col width
|
||||
flex-basis: percentage($col/$sum);
|
||||
}
|
||||
|
||||
@for $c from 1 through $default_sum {
|
||||
.col-#{$c} {
|
||||
@include col($c);
|
||||
}
|
||||
|
||||
// small
|
||||
.small-col-#{$c} {
|
||||
@media only screen and (max-width: $small-bp) {
|
||||
@include col($c);
|
||||
}
|
||||
}
|
||||
|
||||
// medium
|
||||
.med-col-#{$c} {
|
||||
@media only screen and (min-width: $small-bp+1) and (max-width: $med-bp) {
|
||||
@include col($c);
|
||||
}
|
||||
}
|
||||
|
||||
// large
|
||||
.large-col-#{$c} {
|
||||
@media only screen and (min-width: $med-bp+1) {
|
||||
@include col($c);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@for $c from 1 through $default_sum - 1 {
|
||||
@for $o from 1 through $default_sum - $c {
|
||||
.col-#{$c}-offset-#{$o} {
|
||||
@include col($c, $o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: replace with align-self:flex-start or flex-end
|
||||
// .col.float-right{
|
||||
// float: right;
|
||||
// padding-right: 0;
|
||||
// padding-left: $default_gap;
|
||||
// }
|
||||
@@ -1,3 +1,5 @@
|
||||
$side-padding:3em;
|
||||
|
||||
body, html{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
@@ -24,12 +26,12 @@ body{
|
||||
header[role="banner"]{
|
||||
flex: 0 0 auto;
|
||||
@extend %layout-element;
|
||||
padding:1em 1em 0 1em;
|
||||
padding:1em $side-padding 0 $side-padding;
|
||||
}
|
||||
section[role="main-content"]{
|
||||
flex:1 1 auto;
|
||||
@extend %layout-element;
|
||||
padding:0 1em 0 1em;
|
||||
padding:0 $side-padding 0 $side-padding;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
$base_font_size:16px;
|
||||
|
||||
// grid
|
||||
$default_gap: 0;
|
||||
$default_sum: 12;
|
||||
$default_gap: 1em;
|
||||
$default_sum: 12; // total number of columns
|
||||
|
||||
$small-bp:768px;
|
||||
$med-bp:1080px;
|
||||
|
||||
+7
-2
@@ -16,7 +16,7 @@
|
||||
</section>
|
||||
<footer role="tools">
|
||||
<History />
|
||||
<Results />
|
||||
<Results v-if="resultsOpened" />
|
||||
<div id="footer-bottom" class="row">
|
||||
<FooterTabs />
|
||||
<Search />
|
||||
@@ -31,7 +31,7 @@ import History from './components/nav/History'
|
||||
import Results from './components/nav/Results'
|
||||
import Search from './components/nav/Search'
|
||||
import FooterTabs from './components/nav/FooterTabs'
|
||||
// import { mapState, mapActions } from 'vuex'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
metaInfo: {
|
||||
@@ -46,6 +46,11 @@ export default {
|
||||
Results,
|
||||
Search,
|
||||
FooterTabs
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
resultsOpened: state => state.Search.opened
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,21 +2,46 @@
|
||||
<div id="footer-tabs" class="col-1">
|
||||
<ul>
|
||||
<li class="history">
|
||||
<span>Historique de consultation</span>
|
||||
<div class="wrapper">
|
||||
<span>Historique de consultation</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class="results">
|
||||
<span>Resultas</span>
|
||||
<div class="wrapper">
|
||||
<span
|
||||
v-if="resultsItems.length && !resultsOpened"
|
||||
title="Ouvrir les resultats"
|
||||
@click.prevent="openResults"
|
||||
@keydown.enter.prevent="openResults"
|
||||
>
|
||||
Resultas
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'FooterTabs',
|
||||
data: () => ({
|
||||
|
||||
})
|
||||
computed: {
|
||||
resultsOpened: {
|
||||
get () { return this.$store.state.Search.opened },
|
||||
set (value) { this.$store.commit('Search/setOpened', value) }
|
||||
},
|
||||
...mapState({
|
||||
resultsItems: state => state.Search.results
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
openResults () {
|
||||
this.resultsOpened = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
<template>
|
||||
<div id="results">
|
||||
<h2>Resultats</h2>
|
||||
<h3 v-if="keys">{{ keys }}</h3>
|
||||
<div class="results-list">
|
||||
<ul v-if="results.length">
|
||||
<li v-for="result in results" :key="result.uuid">
|
||||
<ResultItem :result="result" />
|
||||
</li>
|
||||
</ul>
|
||||
<transition name="fade-roll">
|
||||
<div
|
||||
v-if="opened"
|
||||
id="results"
|
||||
class="row"
|
||||
>
|
||||
<section class="col-1">
|
||||
<h2>Resultats</h2>
|
||||
<span class="results-count">{{ results.length }} resultat(s)</span>
|
||||
</section>
|
||||
<section class="col-10 results-list">
|
||||
<div class="wrapper">
|
||||
<ul v-if="results.length">
|
||||
<li v-for="result in results" :key="result.uuid" class="result">
|
||||
<ResultItem :result="result" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<section class="col-1 tools">
|
||||
<span
|
||||
class="mdi mdi-close"
|
||||
title="close"
|
||||
@click.prevent="close"
|
||||
@keydown.enter.prevent="close"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -23,14 +40,21 @@ export default {
|
||||
components: {
|
||||
ResultItem
|
||||
},
|
||||
data: () => ({
|
||||
|
||||
}),
|
||||
computed: {
|
||||
opened: {
|
||||
get () { return this.$store.state.Search.opened },
|
||||
set (value) { this.$store.commit('Search/setOpened', value) }
|
||||
},
|
||||
...mapState({
|
||||
keys: state => state.Search.keys,
|
||||
results: state => state.Search.results
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
close () {
|
||||
console.log('clicked on close results')
|
||||
this.opened = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,28 +1,42 @@
|
||||
<template>
|
||||
<div id="search" class="col-11">
|
||||
<form class="" action="index.html" method="post">
|
||||
<label htmlFor="keys">Search</label>
|
||||
<form class="search-form">
|
||||
<label for="keys">Search</label>
|
||||
<input
|
||||
id="keys"
|
||||
v-model="keys"
|
||||
type="text"
|
||||
placeholder="search"
|
||||
@keydown.enter.prevent="submit"
|
||||
>
|
||||
<input
|
||||
id="search"
|
||||
<span
|
||||
v-if="!isloading"
|
||||
class="mdi mdi-magnify"
|
||||
title="rechercher"
|
||||
@click.prevent="submit"
|
||||
@keydown.enter.prevent="submit"
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
class="mdi mdi-loading"
|
||||
title="chargement"
|
||||
/>
|
||||
<!-- <input
|
||||
id="submit-search"
|
||||
type="submit"
|
||||
name="search"
|
||||
value="Search"
|
||||
class="mdi mdi-magnify"
|
||||
@click.prevent="submit"
|
||||
@keyup.enter="submit"
|
||||
>
|
||||
> -->
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapActions } from 'vuex'
|
||||
import { mapActions, mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'Search',
|
||||
@@ -33,7 +47,10 @@ export default {
|
||||
keys: {
|
||||
get () { return this.$store.state.Search.keys },
|
||||
set (value) { this.$store.commit('Search/setKeys', value) }
|
||||
}
|
||||
},
|
||||
...mapState({
|
||||
isloading: state => state.Search.isloading
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
|
||||
@@ -7,7 +7,9 @@ export default {
|
||||
// initial state
|
||||
state: {
|
||||
keys: '',
|
||||
results: []
|
||||
results: [],
|
||||
isloading: false,
|
||||
opened: false
|
||||
},
|
||||
|
||||
// getters
|
||||
@@ -20,6 +22,12 @@ export default {
|
||||
},
|
||||
setResults (state, content) {
|
||||
state.results = content
|
||||
},
|
||||
setIsloading (state, isloading) {
|
||||
state.isloading = isloading
|
||||
},
|
||||
setOpened (state, opened) {
|
||||
state.opened = opened
|
||||
}
|
||||
},
|
||||
|
||||
@@ -27,6 +35,7 @@ export default {
|
||||
actions: {
|
||||
getResults ({ dispatch, commit, state }) {
|
||||
console.log('getResults', state.keys)
|
||||
commit('setIsloading', true)
|
||||
let params = {
|
||||
search: state.keys
|
||||
}
|
||||
@@ -35,10 +44,13 @@ export default {
|
||||
return REST.get(`/search?` + q)
|
||||
.then(({ data }) => {
|
||||
console.log('search REST: data', data)
|
||||
commit('setIsloading', false)
|
||||
commit('setOpened', true)
|
||||
commit('setResults', data.content)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('Issue with search', error)
|
||||
commit('setIsloading', false)
|
||||
Promise.reject(error)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user