Add search icon; move search bar to /search

This commit is contained in:
Robbie Antenesse 2019-09-25 16:41:45 -06:00
parent 8e9f74a901
commit eab60fe159
17 changed files with 104 additions and 74 deletions

View File

@ -19,6 +19,15 @@ Font license info
Homepage: http://typicons.com/
## Iconic
Copyright (C) 2012 by P.J. Onori
Author: P.J. Onori
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://somerandomdude.com/work/iconic/
## Fontelico
Copyright (C) 2012 by Fontello project

View File

@ -8,6 +8,7 @@
.icon-reload:before { content: '\e806'; } /* '' */
.icon-check:before { content: '\e807'; } /* '' */
.icon-plus:before { content: '\e808'; } /* '' */
.icon-search:before { content: '\e809'; } /* '' */
.icon-loading:before { content: '\e839'; } /* '' */
.icon-external:before { content: '\f08e'; } /* '' */
.icon-star-half:before { content: '\f123'; } /* '' */

File diff suppressed because one or more lines are too long

View File

@ -8,6 +8,7 @@
.icon-reload { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-check { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-search { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-loading { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-external { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-star-half { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }

View File

@ -19,6 +19,7 @@
.icon-reload { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-check { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-search { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-loading { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-external { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-star-half { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }

View File

@ -1,11 +1,11 @@
@font-face {
font-family: 'icons';
src: url('../font/icons.eot?91391620');
src: url('../font/icons.eot?91391620#iefix') format('embedded-opentype'),
url('../font/icons.woff2?91391620') format('woff2'),
url('../font/icons.woff?91391620') format('woff'),
url('../font/icons.ttf?91391620') format('truetype'),
url('../font/icons.svg?91391620#icons') format('svg');
src: url('../font/icons.eot?3055787');
src: url('../font/icons.eot?3055787#iefix') format('embedded-opentype'),
url('../font/icons.woff2?3055787') format('woff2'),
url('../font/icons.woff?3055787') format('woff'),
url('../font/icons.ttf?3055787') format('truetype'),
url('../font/icons.svg?3055787#icons') format('svg');
font-weight: normal;
font-style: normal;
}
@ -15,7 +15,7 @@
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'icons';
src: url('../font/icons.svg?91391620#icons') format('svg');
src: url('../font/icons.svg?3055787#icons') format('svg');
}
}
*/
@ -64,6 +64,7 @@
.icon-reload:before { content: '\e806'; } /* '' */
.icon-check:before { content: '\e807'; } /* '' */
.icon-plus:before { content: '\e808'; } /* '' */
.icon-search:before { content: '\e809'; } /* '' */
.icon-loading:before { content: '\e839'; } /* '' */
.icon-external:before { content: '\f08e'; } /* '' */
.icon-star-half:before { content: '\f123'; } /* '' */

View File

@ -229,11 +229,11 @@ body {
}
@font-face {
font-family: 'icons';
src: url('./font/icons.eot?91427620');
src: url('./font/icons.eot?91427620#iefix') format('embedded-opentype'),
url('./font/icons.woff?91427620') format('woff'),
url('./font/icons.ttf?91427620') format('truetype'),
url('./font/icons.svg?91427620#icons') format('svg');
src: url('./font/icons.eot?21491342');
src: url('./font/icons.eot?21491342#iefix') format('embedded-opentype'),
url('./font/icons.woff?21491342') format('woff'),
url('./font/icons.ttf?21491342') format('truetype'),
url('./font/icons.svg?21491342#icons') format('svg');
font-weight: normal;
font-style: normal;
}
@ -311,8 +311,11 @@ body {
</div>
<div class="row">
<div class="the-icons span3" title="Code: 0xe808"><i class="demo-icon icon-plus">&#xe808;</i> <span class="i-name">icon-plus</span><span class="i-code">0xe808</span></div>
<div class="the-icons span3" title="Code: 0xe809"><i class="demo-icon icon-search">&#xe809;</i> <span class="i-name">icon-search</span><span class="i-code">0xe809</span></div>
<div class="the-icons span3" title="Code: 0xe839"><i class="demo-icon icon-loading animate-spin">&#xe839;</i> <span class="i-name">icon-loading</span><span class="i-code">0xe839</span></div>
<div class="the-icons span3" title="Code: 0xf08e"><i class="demo-icon icon-external">&#xf08e;</i> <span class="i-name">icon-external</span><span class="i-code">0xf08e</span></div>
</div>
<div class="row">
<div class="the-icons span3" title="Code: 0xf123"><i class="demo-icon icon-star-half">&#xf123;</i> <span class="i-name">icon-star-half</span><span class="i-code">0xf123</span></div>
</div>
</div>

Binary file not shown.

View File

@ -24,6 +24,8 @@
<glyph glyph-name="plus" unicode="&#xe808;" d="M729 454q44 0 74-31t31-73-31-73-74-30l-208 3 0-212q0-43-30-73t-75-31-73 31-30 73l3 212-212-3q-44 0-74 30t-30 73 30 73 74 31l212 0-3 209q0 42 30 73t73 31 75-31 30-73l0-209 208 0z" horiz-adv-x="834" />
<glyph glyph-name="search" unicode="&#xe809;" d="M335 246l25-25q-28-28-85-86t-73-74l-27 27q16 15 74 73t86 85z m245 551q136 0 234-97t97-234-97-234-234-96q-64 0-123 24l-255-257-184 185 256 255q-26 63-26 123 0 137 98 234t234 97z m0-551q91 0 155 64t64 156-64 155-155 64-156-64-64-155 64-156 156-64z" horiz-adv-x="928" />
<glyph glyph-name="loading" unicode="&#xe839;" d="M855 9c-189-190-520-172-705 13-190 190-200 494-28 695 11 13 21 26 35 34 36 23 85 18 117-13 30-31 35-76 16-112-5-9-9-15-16-22-140-151-145-379-8-516 153-153 407-121 542 34 106 122 142 297 77 451-83 198-305 291-510 222l0 1c236 82 492-24 588-252 71-167 37-355-72-493-11-15-23-29-36-42z" horiz-adv-x="1000" />
<glyph glyph-name="external" unicode="&#xf08e;" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -77,6 +77,12 @@
"css": "reload",
"code": 59398,
"src": "fontawesome"
},
{
"uid": "c6344a6ed148da12354cc90705287696",
"css": "search",
"code": 59401,
"src": "iconic"
}
]
}

View File

@ -2,7 +2,7 @@
"name": "English",
"locale": "en",
"global": {
"searchbar_placeholder": "Search for Books",
"menu_search": "Search for Books",
"menu_login": "Log In",
"menu_logout": "Log Out",
"footer_repo": "Repo",
@ -35,8 +35,9 @@
},
"search": {
"header": "Search",
"placeholder": "Search for Books",
"button_text": "Search",
"loading": "Loading...",
"results_header": "Results for:",
"no_results": "None Found",
"no_results_suggestion": "If you're expecting book data, go and help fill out the Inventaire database!",
"people_header": "People",

View File

@ -18,14 +18,7 @@ export const globalView = (state, emit, i18n, view) => {
<label for="navMenu" class="burger pseudo button">${'\u2261'}</label>
<div class="menu">
<label style="display: inline-block;">
<input type="text" name="search"
placeholder=${i18n.__('global.searchbar_placeholder')}
onchange=${e => {
emit('pushState', '/search?for=' + encodeURIComponent(e.target.value.trim()));
}}
>
</label>
<a href="/search" class="pseudo button"><i class="icon-search" aria-label=${i18n.__('global.menu_search')}></i></a>
<a href="/login" class="pseudo button">${i18n.__('global.menu_login')}</a>
<a href="/logout" class="pseudo button">${i18n.__('global.menu_logout')}</a>
</div>

View File

@ -5,8 +5,8 @@ export class SearchController extends ViewController {
// Super passes state, view name, and default state to ViewController,
// which stores state in this.appState and the view controller's state to this.state
super(state, i18n, 'search', {
lastSearch: undefined,
done: false,
lastSearch: '',
done: true,
results: {
humans: [],
series: [],
@ -34,6 +34,10 @@ export class SearchController extends ViewController {
return this.appState.query.hasOwnProperty('for') && this.appState.query.for.trim() !== '';
}
get queryIsNew() {
return this.state.lastSearch !== this.appState.query.for.trim();
}
get openModal() {
return this.state.openModal;
}

View File

@ -8,58 +8,65 @@ export const searchView = (state, emit, i18n) => {
const controller = new SearchController(state, emit, i18n);
const { __ } = controller.i18n;
if (controller.state.lastSearch !== state.query.for) {
if (controller.hasQuery && controller.queryIsNew) {
controller.search();
}
// Returning an array in a view allows non-shared parent HTML elements.
// This one doesn't have the problem right now, but it's good to remember.
return [
html`<section>
<h1 class="title">${__('search.header')}</h1>
<article>
<div class="flex">
<div class="two-third-700">
<h2>
${controller.doneSearching
? html`<span>${__('search.results_header')}</span> <code>${controller.state.lastSearch}</code>`
: html`<span>${__('search.loading')}</span>`
}
</h2>
</div>
<div class="one-third-700">
${controller.doneSearching
? html`<span class="pull-right" data-tooltip=${__('interaction.reload')}>
<button class="pseudo" onclick=${() => controller.search()}>
<i class="icon-reload"></i>
</button>
</span>`
: html`<i class="icon-loading animate-spin"></i>`
}
</div>
</div>
html`<h1 class="title">${__('search.header')}</h1>`,
${!controller.doneSearching || controller.results.works < 1
? [
html`<h3>${__('search.no_results')}</h3>`,
html`<a class="button" href="https://wiki.inventaire.io/wiki/How-to-contribute" target="_blank">
${__('search.no_results_suggestion')}
</a>`
]
: controller.results.works.map(result => {
return html`<div class="flex search-result">
<div class="two-third-800 half-500">
<h3 class="title">${result.name}</h3>
${result.description ? html`<h4 class="subtitle">${result.description}</h4>` : null}
</div>
<div class="third-800 half-500">
${resultDetails(controller, result, emit)}
</div>
</div>`;
})
html`<section class="flex">
<label class="three-fourth">
<input type="text" name="search"
aria-label=${i18n.__('search.placeholder')}
placeholder=${i18n.__('search.placeholder')}
value=${controller.state.lastSearch}
onchange=${e => {
emit('pushState', '/search?for=' + encodeURIComponent(e.target.value.trim()));
}}
${!controller.doneSearching ? 'disabled' : null}
>
</label>
<button class="fourth" style="margin-top:0;height:2.1em;" onclick=${() => controller.search()} ${!controller.doneSearching ? 'disabled' : null}>
${!controller.doneSearching
? html`<i class="icon-loading animate-spin"></i>`
: __('search.button_text')
}
</button>
</section>`,
html`<section>
</section>`,
html`<section>
<h2>
${controller.hasQuery && !controller.doneSearching
? html`<span>${__('search.loading')}</span> <i class="icon-loading animate-spin"></i>`
: null
}
</article>
</h2>
${controller.hasQuery && controller.doneSearching && controller.results.works < 1
? [
html`<h3>${__('search.no_results')}</h3>`,
html`<a class="button" href="https://wiki.inventaire.io/wiki/How-to-contribute" target="_blank">
${__('search.no_results_suggestion')}
</a>`
]
: controller.results.works.map(result => {
return html`<article class="flex search-result">
<header class="two-third-800 half-500">
<h3 class="title">${result.name}</h3>
${result.description ? html`<h4 class="subtitle">${result.description}</h4>` : null}
</header>
<footer class="third-800 half-500">
${resultDetails(controller, result, emit)}
</footer>
</article>`;
})
}
</section>`,
];
}