Merge Request #45
Search - new UI field
Fixes #94
The UI was completely changed to a new concept for better usability. The changes below were implemented:
New search button on navbar

Changed the field fixed on navbar to the full content fixed on top.

Remove the field on results to a tag with the text used on result

| 1 | -<li class="dropdown profile-menu" uib-dropdown> | 1 | +<li class="dropdown profile-menu btn-nav" uib-dropdown> |
| 2 | <a href="#" class="dropdown-toggle" aria-expanded="false" uib-dropdown-toggle> | 2 | <a href="#" class="dropdown-toggle" aria-expanded="false" uib-dropdown-toggle> |
| 3 | <span>{{"language.selector" | translate}}</span> <b class="caret"></b> | 3 | <span>{{"language.selector" | translate}}</span> <b class="caret"></b> |
| 4 | </a> | 4 | </a> |
| @@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
| 16 | </ul> | 16 | </ul> |
| 17 | 17 | ||
| 18 | <ul class="nav navbar-nav navbar-right"> | 18 | <ul class="nav navbar-nav navbar-right"> |
| 19 | - <li ng-show="!ctrl.currentUser"> | 19 | + <li class="btn-nav" ng-show="!ctrl.currentUser"> |
| 20 | <a ng-href="#" ng-click="ctrl.openLogin()">{{"navbar.login" | translate}}</a> | 20 | <a ng-href="#" ng-click="ctrl.openLogin()">{{"navbar.login" | translate}}</a> |
| 21 | </li> | 21 | </li> |
| 22 | 22 | ||
| @@ -51,4 +51,4 @@ | @@ -51,4 +51,4 @@ | ||
| 51 | </div> | 51 | </div> |
| 52 | </nav> | 52 | </nav> |
| 53 | <div ui-view="toolbar"> | 53 | <div ui-view="toolbar"> |
| 54 | -</div> | ||
| 55 | \ No newline at end of file | 54 | \ No newline at end of file |
| 55 | +</div> |
| @@ -15,3 +15,36 @@ | @@ -15,3 +15,36 @@ | ||
| 15 | content: $content; | 15 | content: $content; |
| 16 | border: $border; | 16 | border: $border; |
| 17 | } | 17 | } |
| 18 | + | ||
| 19 | +@mixin opacity($opacity) { | ||
| 20 | + /* Netscape */ | ||
| 21 | + -moz-opacity: $opacity; | ||
| 22 | + | ||
| 23 | + /* Safari 1.x */ | ||
| 24 | + -khtml-opacity: $opacity; | ||
| 25 | + | ||
| 26 | + /* Good browsers */ | ||
| 27 | + opacity: $opacity; | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +@mixin transition($args...) { | ||
| 31 | + | ||
| 32 | + $duration: 300ms; | ||
| 33 | + $keys: keywords($args); | ||
| 34 | + @if map-has-key($keys, duration) { | ||
| 35 | + $duration: map-get($keys, duration); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + -webkit-transition: $args; | ||
| 39 | + -o-transition: $args; | ||
| 40 | + transition: $args; | ||
| 41 | + -webkit-transition-duration: $duration; | ||
| 42 | + transition-duration: $duration; | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +@mixin outline($style: none, $width: 0px) { | ||
| 46 | + &:focus { | ||
| 47 | + outline-style: $style; | ||
| 48 | + outline-width: $width; | ||
| 49 | + } | ||
| 50 | +} |
| @@ -7,6 +7,15 @@ $whbl-font-color: #16191c; | @@ -7,6 +7,15 @@ $whbl-font-color: #16191c; | ||
| 7 | #header-navbar { | 7 | #header-navbar { |
| 8 | background-color: $whbl-primary-color; | 8 | background-color: $whbl-primary-color; |
| 9 | } | 9 | } |
| 10 | + | ||
| 11 | + .navbar { | ||
| 12 | + .btn-nav { | ||
| 13 | + &:hover { | ||
| 14 | + background-color: #1b86ba; | ||
| 15 | + } | ||
| 16 | + } | ||
| 17 | + } | ||
| 18 | + | ||
| 10 | .navbar > .container .navbar-brand { | 19 | .navbar > .container .navbar-brand { |
| 11 | background-color: transparent; | 20 | background-color: transparent; |
| 12 | width: 221px; | 21 | width: 221px; |
| @@ -21,8 +21,8 @@ describe("Components", () => { | @@ -21,8 +21,8 @@ describe("Components", () => { | ||
| 21 | helper = new ComponentTestHelper<SearchFormComponent>(cls, done); | 21 | helper = new ComponentTestHelper<SearchFormComponent>(cls, done); |
| 22 | }); | 22 | }); |
| 23 | 23 | ||
| 24 | - it("render a input for search query", () => { | ||
| 25 | - expect(helper.find(".search-input").length).toEqual(1); | 24 | + it("render a button that open a search query field", () => { |
| 25 | + expect(helper.find(".btn-search-nav").length).toEqual(1); | ||
| 26 | }); | 26 | }); |
| 27 | 27 | ||
| 28 | it("go to search page when click on search button", () => { | 28 | it("go to search page when click on search button", () => { |
| 1 | -<form class="navbar-form search-form" role="search" ng-if="!ctrl.isSearchPage()"> | ||
| 2 | - <div class="input-group"> | ||
| 3 | - <input type="text" class="search-input form-control" placeholder="Search" name="q" ng-model="ctrl.query"> | ||
| 4 | - <div class="input-group-btn"> | ||
| 5 | - <button class="btn btn-default" type="submit" (click)="ctrl.search()"><i class="fa fa-search fa-fw"></i></button> | 1 | +<a class="btn btn-nav" ng-click="showSearch = !showSearch"> |
| 2 | + <i class="fa fa-search btn-search-nav" aria-hidden="true"></i> | ||
| 3 | +</a> | ||
| 4 | +<form class="navbar-form search-form" role="search"> | ||
| 5 | + <div class="ng-scope" ng-class="{'top-search-wrap': !showSearch, 'top-search-toggled': showSearch}"> | ||
| 6 | + <div class="tsw-inner"> | ||
| 7 | + <i id="top-search-close" class="fa fa-chevron-left" aria-hidden="true" ng-click="showSearch = false"></i> | ||
| 8 | + <input type="text" placeholder="{{ 'search.label' | translate }}" name="q" ng-model="ctrl.query"> | ||
| 9 | + <i class="fa fa-search btn-search" aria-hidden="true" (click)="ctrl.search()"></i> | ||
| 10 | + <button type="submit" (click)="ctrl.search()"></i> | ||
| 6 | </div> | 11 | </div> |
| 7 | </div> | 12 | </div> |
| 8 | </form> | 13 | </form> |
| @@ -0,0 +1,107 @@ | @@ -0,0 +1,107 @@ | ||
| 1 | +/** | ||
| 2 | +* TODO: Remove the temporary reimport mixins | ||
| 3 | +* Maybe the cause for this is in gulp/styles.js | ||
| 4 | +* task on compile sass order. | ||
| 5 | +*/ | ||
| 6 | +@import "../../layout/scss/mixins"; | ||
| 7 | + | ||
| 8 | +@mixin search-wrap-btn { | ||
| 9 | + @include border-radius(2px 0px 0px 2px); | ||
| 10 | + @content; | ||
| 11 | + font-size: 23px; | ||
| 12 | + font-style: normal; | ||
| 13 | + width: 45px; | ||
| 14 | + text-align: center; | ||
| 15 | + cursor: pointer; | ||
| 16 | + height: 40px; | ||
| 17 | + padding-top: 9px; | ||
| 18 | + | ||
| 19 | + background-color: #e3e3e3; | ||
| 20 | + &:hover { | ||
| 21 | + background-color: #D1D1D1; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + @include outline(none); | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +.top-search-wrap { | ||
| 28 | + @include opacity(0); | ||
| 29 | + @include transition(all); | ||
| 30 | + | ||
| 31 | + position: absolute; | ||
| 32 | + top: -65px; | ||
| 33 | + left: 0; | ||
| 34 | + width: 100%; | ||
| 35 | + height: 70px; | ||
| 36 | + background: #fff; | ||
| 37 | + z-index: 10; | ||
| 38 | + | ||
| 39 | + .tsw-inner { | ||
| 40 | + position: relative; | ||
| 41 | + padding: 15px; | ||
| 42 | + max-width: 700px; | ||
| 43 | + display: block; | ||
| 44 | + margin: 0 auto; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + #top-search-close { | ||
| 48 | + @include border-radius(2px 0px 0px 2px); | ||
| 49 | + @include search-wrap-btn { | ||
| 50 | + position: absolute; | ||
| 51 | + top: 15px; | ||
| 52 | + left: 15px; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + @include outline(none); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + .btn-search { | ||
| 59 | + display: inline; | ||
| 60 | + float: right; | ||
| 61 | + | ||
| 62 | + @include search-wrap-btn { | ||
| 63 | + position: relative; | ||
| 64 | + top: -40px; | ||
| 65 | + left: 0px; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + input[type="text"] { | ||
| 71 | + @include border-radius(2px); | ||
| 72 | + border: 0; | ||
| 73 | + height: 40px; | ||
| 74 | + padding: 0 10px 0 55px; | ||
| 75 | + font-size: 18px; | ||
| 76 | + width: 500px; | ||
| 77 | + background-color: #efefef; | ||
| 78 | + width: 100%; | ||
| 79 | + | ||
| 80 | + @include outline(none); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +.top-search-toggled { | ||
| 86 | + @extend .top-search-wrap; | ||
| 87 | + @include opacity(1); | ||
| 88 | + position: fixed; | ||
| 89 | + top: 0; | ||
| 90 | + box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3); | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +.btn-nav { | ||
| 94 | + .btn-search-nav { | ||
| 95 | + font-size: 25px; | ||
| 96 | + color: #FFF; | ||
| 97 | + cursor: pointer; | ||
| 98 | + padding: 1px; | ||
| 99 | + } | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | + | ||
| 103 | +.search-form { | ||
| 104 | + button[type="submit"] { | ||
| 105 | + visibility: hidden; | ||
| 106 | + } | ||
| 107 | +} |
| @@ -23,7 +23,7 @@ export class SearchComponent { | @@ -23,7 +23,7 @@ export class SearchComponent { | ||
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | search() { | 25 | search() { |
| 26 | - this.$state.go('main.environment.search', { query: this.query }); | 26 | + this.$state.go('main.environment.search', { query: this.query }); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | loadPage() { | 29 | loadPage() { |
| 1 | <form ng-submit="ctrl.search()"> | 1 | <form ng-submit="ctrl.search()"> |
| 2 | <label for="query" ng-bind-html="'search.results.query.label' | translate"></label> | 2 | <label for="query" ng-bind-html="'search.results.query.label' | translate"></label> |
| 3 | -<input id="query" placeholder="{{'search.results.query.placeholder' | translate}}" type="search" class="search-box-title" ng-model="ctrl.query"> | 3 | +<h3 id="query" class="search-box-title">{{ctrl.query}}</h3> |
| 4 | </form> | 4 | </form> |
| 5 | <div class="search-results"> | 5 | <div class="search-results"> |
| 6 | <div class="summary"> | 6 | <div class="summary"> |
| @@ -2,7 +2,6 @@ | @@ -2,7 +2,6 @@ | ||
| 2 | .summary { | 2 | .summary { |
| 3 | color: #bbbbbb; | 3 | color: #bbbbbb; |
| 4 | font-size: 13px; | 4 | font-size: 13px; |
| 5 | - border-top: 1px solid #ececec; | ||
| 6 | } | 5 | } |
| 7 | .result { | 6 | .result { |
| 8 | margin: 25px 0; | 7 | margin: 25px 0; |
| @@ -45,4 +44,4 @@ | @@ -45,4 +44,4 @@ | ||
| 45 | 44 | ||
| 46 | .search-box-title:focus { | 45 | .search-box-title:focus { |
| 47 | outline: none; | 46 | outline: none; |
| 48 | -} | ||
| 49 | \ No newline at end of file | 47 | \ No newline at end of file |
| 48 | +} |
| @@ -81,8 +81,8 @@ | @@ -81,8 +81,8 @@ | ||
| 81 | "designMode.toggle.ON": "ON", | 81 | "designMode.toggle.ON": "ON", |
| 82 | "designMode.toggle.OFF": "OFF", | 82 | "designMode.toggle.OFF": "OFF", |
| 83 | "search.results.summary": "{results, plural, one{result} other{# results}}", | 83 | "search.results.summary": "{results, plural, one{result} other{# results}}", |
| 84 | - "search.results.query.label": "Search for:", | ||
| 85 | - "search.results.query.placeholder": "Search", | 84 | + "search.results.query.label": "Search therm:", |
| 85 | + "search.label": "Search", | ||
| 86 | "block.edit": "Edit", | 86 | "block.edit": "Edit", |
| 87 | "block.edition.title": "Edit Block", | 87 | "block.edition.title": "Edit Block", |
| 88 | "block.edition.success.title": "Good job!", | 88 | "block.edition.success.title": "Good job!", |
| @@ -81,8 +81,8 @@ | @@ -81,8 +81,8 @@ | ||
| 81 | "designMode.toggle.ON": "Ligado", | 81 | "designMode.toggle.ON": "Ligado", |
| 82 | "designMode.toggle.OFF": "Desligado", | 82 | "designMode.toggle.OFF": "Desligado", |
| 83 | "search.results.summary": "{results, plural, one{# resultado} other{# resultados}}", | 83 | "search.results.summary": "{results, plural, one{# resultado} other{# resultados}}", |
| 84 | - "search.results.query.label": "Buscar:", | ||
| 85 | - "search.results.query.placeholder": "Informe aqui sua busca", | 84 | + "search.results.query.label": "Termo da busca:", |
| 85 | + "search.label": "Pesquisar", | ||
| 86 | "block.edit": "Editar", | 86 | "block.edit": "Editar", |
| 87 | "block.edition.title": "Editar Bloco", | 87 | "block.edition.title": "Editar Bloco", |
| 88 | "block.edition.success.title": "Bom trabalho!", | 88 | "block.edition.success.title": "Bom trabalho!", |
-
Acredito a área de busca deveria retrair-se quando o usuário clicasse em qualquer lugar que não fosse no campo de busca. Da forma como está, para fechar esta área o usuário é obrigado a clicar numa seta para esquerda localizada do lado esquerdo do campo de busca.
Penso também que seria melhor utilizar uma abordagem retrátil semelhante ao tema "Cube Bootstrap". A abordagem do "Cube Boostrap" já inclui a minha sugestão acima.
-
Assignee removed
-
@maljunior A abordagem do tema que vc se refere ocupa um certo espaço na barra de cabeçalho (header) que inclusive irá conter vários outros elementos futuramente, como novos itens de menu a esquerda próximo a logo, e itens de notificação de mensagens e do sistema a direita. A "solução" adotada pelo tema que vc mencionou foi colocar um campo de busca bem pequeno, o que compromete consideravelmente na inserção de textos maiores. Além disso, dessa forma seria necessário um ajuste específico para a responsividade, o que demanda + tempo e uma implementação talvez até mesmo desnecessária.
Sobre esconder a barra de busca, já havia sido identificado como melhoria, não sendo bloqueante ou essencial para conclusão da tarefa !!
Como referência e melhor visualização, por favor, verifique os links abaixo:
-
mentioned in commit 8a083fd6ad364a8532c3a33c7dbc900736d9ee16