add backdrop for suggestions and show suggestions loading spinner the moment a user starts typing (#129)
fixes #118 fixes #122
This commit is contained in:
parent
a3ed2036cb
commit
71eba22a0e
|
@ -149,7 +149,7 @@ init channel query show from size model =
|
||||||
( { channel = Maybe.withDefault defaultChannel channel
|
( { channel = Maybe.withDefault defaultChannel channel
|
||||||
, queryDebounce =
|
, queryDebounce =
|
||||||
Debouncer.Messages.manual
|
Debouncer.Messages.manual
|
||||||
|> Debouncer.Messages.settleWhenQuietFor (Just <| Debouncer.Messages.fromSeconds 0.6)
|
|> Debouncer.Messages.settleWhenQuietFor (Just <| Debouncer.Messages.fromSeconds 0.4)
|
||||||
|> Debouncer.Messages.toDebouncer
|
|> Debouncer.Messages.toDebouncer
|
||||||
, query = query
|
, query = query
|
||||||
, querySuggest =
|
, querySuggest =
|
||||||
|
@ -264,22 +264,7 @@ update path navKey result_type options decodeResultItemSource msg model =
|
||||||
(QueryInputDebounce (Debouncer.Messages.provideInput QueryInputSuggestionsSubmit))
|
(QueryInputDebounce (Debouncer.Messages.provideInput QueryInputSuggestionsSubmit))
|
||||||
{ model
|
{ model
|
||||||
| query = Just query
|
| query = Just query
|
||||||
, querySuggest =
|
, querySuggest = RemoteData.Loading
|
||||||
case model.querySuggest of
|
|
||||||
RemoteData.Success result ->
|
|
||||||
let
|
|
||||||
suggestions =
|
|
||||||
getSuggestions (Just "XXXX") model.querySuggest
|
|
||||||
|> List.map .text
|
|
||||||
in
|
|
||||||
if List.member (Just query) suggestions then
|
|
||||||
RemoteData.NotAsked
|
|
||||||
|
|
||||||
else
|
|
||||||
model.querySuggest
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
RemoteData.NotAsked
|
|
||||||
, querySelectedSuggestion = Nothing
|
, querySelectedSuggestion = Nothing
|
||||||
}
|
}
|
||||||
|> Tuple.mapSecond
|
|> Tuple.mapSecond
|
||||||
|
@ -708,14 +693,25 @@ view path title model viewSuccess outMsg =
|
||||||
[ text <| Maybe.withDefault "" x.text ]
|
[ text <| Maybe.withDefault "" x.text ]
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
div [ class "search-page" ]
|
div
|
||||||
|
[ classList
|
||||||
|
[ ( "search-page", True )
|
||||||
|
, ( "with-suggestions", RemoteData.isSuccess model.querySuggest && List.length suggestions > 0 )
|
||||||
|
, ( "with-suggestions-loading"
|
||||||
|
, (model.query /= Nothing)
|
||||||
|
&& (model.query /= Just "")
|
||||||
|
&& not (RemoteData.isSuccess model.querySuggest || RemoteData.isNotAsked model.querySuggest)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
]
|
||||||
[ h1 [ class "page-header" ] [ text title ]
|
[ h1 [ class "page-header" ] [ text title ]
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ class "search-backdrop"
|
||||||
[ ( "search-input", True )
|
, onClick <| outMsg SuggestionsClose
|
||||||
, ( "with-suggestions", RemoteData.isSuccess model.querySuggest && List.length suggestions > 0 )
|
]
|
||||||
, ( "with-suggestions-loading", RemoteData.isLoading model.querySuggest )
|
[]
|
||||||
]
|
, div
|
||||||
|
[ class "search-input"
|
||||||
]
|
]
|
||||||
[ form [ onSubmit (outMsg QueryInputSubmit) ]
|
[ form [ onSubmit (outMsg QueryInputSubmit) ]
|
||||||
[ p
|
[ p
|
||||||
|
|
205
src/index.scss
205
src/index.scss
|
@ -29,107 +29,114 @@ header .navbar.navbar-static-top {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-page {
|
.search-page.with-suggestions-loading {
|
||||||
.search-input.with-suggestions-loading {
|
.input-append div.loader {
|
||||||
.input-append div.loader {
|
display: block;
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.search-input.with-suggestions {
|
|
||||||
ul.dropdown-menu {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.input-append input {
|
|
||||||
border-radius: 4px 0 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.search-input {
|
|
||||||
position: relative;
|
|
||||||
ul.dropdown-menu {
|
|
||||||
font-size: 18px;
|
|
||||||
width: 25.6em;
|
|
||||||
height: auto;
|
|
||||||
max-height: 200px;
|
|
||||||
border-radius: 0;
|
|
||||||
margin-top: -10px;
|
|
||||||
border-top: 0;
|
|
||||||
overflow-y: scroll;
|
|
||||||
li > a {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
li > a#dropdown-menu-selected {
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: #0081c2;
|
|
||||||
background-image: -moz-linear-gradient(top,#08c,#0077b3);
|
|
||||||
background-image: -webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));
|
|
||||||
background-image: -webkit-linear-gradient(top,#08c,#0077b3);
|
|
||||||
background-image: -o-linear-gradient(top,#08c,#0077b3);
|
|
||||||
background-image: linear-gradient(to bottom,#08c,#0077b3);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.input-append {
|
|
||||||
position: relative;
|
|
||||||
input {
|
|
||||||
font-size: 18px;
|
|
||||||
height: 40px;
|
|
||||||
width: 25em;
|
|
||||||
}
|
|
||||||
div.loader {
|
|
||||||
display: none;
|
|
||||||
z-index: 100;
|
|
||||||
position: absolute;
|
|
||||||
margin: 0;
|
|
||||||
top: 37px;
|
|
||||||
right: 125px;
|
|
||||||
font-size: 6px;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
font-size: 24px;
|
|
||||||
height: 50px;
|
|
||||||
min-width: 4em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
form > p > strong {
|
|
||||||
vertical-align: middle;
|
|
||||||
font-size: 1.2em;
|
|
||||||
margin-left: 0.2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.search-result {
|
|
||||||
tbody > tr {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
tbody > td > dl > dd > ul.inline {
|
|
||||||
margin: 0;
|
|
||||||
li {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
li::after {
|
|
||||||
content: ", ";
|
|
||||||
padding-right: 0.5em;
|
|
||||||
}
|
|
||||||
li:last-child::after {
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tbody > td > dl > dd > pre {
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
padding: 0;
|
|
||||||
line-height: 20px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
tbody > td > dl > dt,
|
|
||||||
tbody > td > dl > dd {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.search-page.with-suggestions {
|
||||||
|
ul.dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.input-append input {
|
||||||
|
border-radius: 4px 0 0 0;
|
||||||
|
}
|
||||||
|
.search-backdrop {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.search-input {
|
||||||
|
position: relative;
|
||||||
|
ul.dropdown-menu {
|
||||||
|
font-size: 18px;
|
||||||
|
width: 25.6em;
|
||||||
|
height: auto;
|
||||||
|
max-height: 200px;
|
||||||
|
border-radius: 0;
|
||||||
|
margin-top: -10px;
|
||||||
|
border-top: 0;
|
||||||
|
overflow-y: scroll;
|
||||||
|
li > a {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
li > a#dropdown-menu-selected {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #0081c2;
|
||||||
|
background-image: -moz-linear-gradient(top,#08c,#0077b3);
|
||||||
|
background-image: -webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));
|
||||||
|
background-image: -webkit-linear-gradient(top,#08c,#0077b3);
|
||||||
|
background-image: -o-linear-gradient(top,#08c,#0077b3);
|
||||||
|
background-image: linear-gradient(to bottom,#08c,#0077b3);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.input-append {
|
||||||
|
position: relative;
|
||||||
|
input {
|
||||||
|
font-size: 18px;
|
||||||
|
height: 40px;
|
||||||
|
width: 25em;
|
||||||
|
}
|
||||||
|
div.loader {
|
||||||
|
display: none;
|
||||||
|
z-index: 100;
|
||||||
|
position: absolute;
|
||||||
|
margin: 0;
|
||||||
|
top: 37px;
|
||||||
|
right: 125px;
|
||||||
|
font-size: 6px;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
font-size: 24px;
|
||||||
|
height: 50px;
|
||||||
|
min-width: 4em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form > p > strong {
|
||||||
|
vertical-align: middle;
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin-left: 0.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.search-result {
|
||||||
|
tbody > tr {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
tbody > td > dl > dd > ul.inline {
|
||||||
|
margin: 0;
|
||||||
|
li {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
li::after {
|
||||||
|
content: ", ";
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
li:last-child::after {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tbody > td > dl > dd > pre {
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 20px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
tbody > td > dl > dt,
|
||||||
|
tbody > td > dl > dd {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.loader,
|
.loader,
|
||||||
.loader:before,
|
.loader:before,
|
||||||
|
|
Loading…
Reference in a new issue