Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style: change survey parameter style #717

Merged
merged 5 commits into from
Jan 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions src/components/Search.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
$: multiple = selectedItems != null;
export let maxSelections = Number.POSITIVE_INFINITY;

/**
* enable modern styling
*/
export let modern = false;

let text;
let filteredTextLength = 0;

Expand Down Expand Up @@ -243,6 +248,11 @@

function onInputClick() {
resetListToAllItemsAndOpen();

if (modern) {
// select the whole field upon click
input.select();
}
}

function onEsc(e) {
Expand Down Expand Up @@ -380,17 +390,44 @@
display: flex;
align-items: center;
}

/* modern styles for survey dashboard */
.search-box.modern {
background: white;
flex: 2 1 auto;
}
.search-icon.modern {
left: 10px;
}
.clear-button.modern {
right: 10px;
}
.uk-search-input.modern {
background: white;
font-weight: 600;
letter-spacing: 3px;
height: 64px;
font-size: 1rem;
line-height: 1.5rem;
padding-left: 50px !important;
padding-top: 10px;
padding-bottom: 10px;
border-radius: 3px;
border: 1px solid #d3d4d8;
}
</style>

<div
class="{className} uk-search search-box"
class:uk-search-default={!multiple}
class:search-multiple={multiple}
class:modern
on:click={onContainerClick}>
{#if !multiple}
<span data-uk-search-icon />
<span class="uk-search-icon search-icon" class:modern data-uk-icon="icon: search" />
<input
class="uk-search-input"
class:modern
{placeholder}
{name}
{disabled}
Expand All @@ -406,11 +443,12 @@
<button
class="uk-search-icon clear-button"
class:hidden={!text}
class:modern
on:click={onResetItem}
title="Clear Search Field"
data-uk-icon="icon: close" />
{:else}
<span class="uk-search-icon search-multiple-icon" data-uk-icon="icon: search" />
<span class="uk-search-icon search-multiple-icon search-icon" data-uk-icon="icon: search" class:modern />

{#each selectedItems as selectedItem}
<div class="search-tag" style="border-color: {colorFieldName ? selectedItem[colorFieldName] : undefined}">
Expand All @@ -426,6 +464,7 @@
{#if !multiple || selectedItems.length < maxSelections}
<input
class="uk-search-input search-multiple-input"
class:modern
{placeholder}
{name}
{disabled}
Expand All @@ -441,6 +480,7 @@
{/if}
<button
class="uk-search-icon clear-button"
class:modern
class:hidden={selectedItems.length === 0}
on:click={onResetItem}
title="Clear Search Field"
Expand Down
72 changes: 51 additions & 21 deletions src/components/SensorDatePicker2.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import calendarIcon from '!raw-loader!@fortawesome/fontawesome-free/svgs/solid/calendar.svg';
import { parseAPITime } from '../data';
import { times } from '../stores';
import { formatDateShortAbbr } from '../formats';
import { formatDateShortOrdinal } from '../formats';
import { timeDay } from 'd3-time';

/**
Expand Down Expand Up @@ -44,34 +44,54 @@
letter-spacing: 3px;
background: none;
font-size: 1rem;
font-weight: 600;
padding: 13px;
line-height: 1;
white-space: nowrap;
}
.arrow {

.arrow-button {
box-sizing: content-box;
background: none;
border: none;
width: 1.2em;
padding: 0;
margin: 0;
padding: 13px;
width: 14px;
height: 15px;
}

.arrow-left {
margin-right: 10px; /* 36 - 13*2 */
}
.wide {
margin-right: 2em;
.arrow-right {
margin-left: 10px; /* 36 - 13*2 */
}

.arrow[disabled] {
opacity: 0.5;
.picker-button {
border-radius: 20px;
}

.picker-button:hover,
.picker-button:focus,
.picker-button:active {
outline: none !important;
border: none !important;
background: rgba(211, 212, 216, 0.25);
}

.picker-button[disabled] {
cursor: not-allowed;
}

.selected-date-icon {
width: 14px;
display: inline-block;
margin-right: 0.5em;
}
</style>

<div class="date-picker {className}">
<button
class="arrow wide"
disabled={value == null || startEndDates.length === 0 || value.valueOf() === startEndDates[1].valueOf()}
title="Go to the latest date for which data is available"
on:click={() => (value = startEndDates[1])}>
{@html calendarIcon}
</button>
<button
class="arrow"
class="arrow-button picker-button arrow-left"
title="Go to the previous day"
disabled={value == null || startEndDates.length === 0 || value <= startEndDates[0]}
on:click={() => (value = timeDay.offset(value, -1))}>
Expand All @@ -82,12 +102,22 @@
bind:selected={value}
start={startEndDates[0]}
end={startEndDates[1]}
formattedSelected={formatDateShortAbbr(value)}>
<button aria-label="selected date" class="selected-date" on:>{formatDateShortAbbr(value)}</button>
formattedSelected={formatDateShortOrdinal(value)}>
<button aria-label="selected date" class="selected-date picker-button" on:>
<span class="selected-date-icon">
{@html calendarIcon}
</span>
<span>{formatDateShortOrdinal(value)}</span></button>
</Datepicker>
{:else}<button aria-label="selected date" class="selected-date" disabled>{formatDateShortAbbr(value)}</button>{/if}
{:else}
<button aria-label="selected date" class="selected-date picker-button" disabled>
<span class="inline-svg-icon">
{@html calendarIcon}
</span>
<span>{formatDateShortOrdinal(value)}</span></button>
{/if}
<button
class="arrow"
class="arrow-button picker-button arrow-right"
title="Go to the next day"
disabled={value == null || startEndDates.length === 0 || value >= startEndDates[1]}
on:click={() => (value = timeDay.offset(value, 1))}>
Expand Down
23 changes: 23 additions & 0 deletions src/formats.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const shortAbbr = timeFormat('%b %d');
const shortNumbers = timeFormat('%m/%d');
const iso = timeFormat('%Y-%m-%d');
const local = timeFormat('%m/%d/%Y');
const shortAbbrNth = timeFormat('%b %-d');

export function formatDateShortNumbers(date) {
return !date ? '?' : shortNumbers(date);
Expand All @@ -18,6 +19,28 @@ export function formatDateShortAbbr(date) {
return !date ? '?' : shortAbbr(date);
}

function nth(d) {
// based on https://stackoverflow.com/questions/15397372/javascript-new-date-ordinal-st-nd-rd-th
if (d > 3 && d < 21) return 'th';
switch (d % 10) {
case 1:
return 'st';
case 2:
return 'nd';
case 3:
return 'rd';
default:
return 'th';
}
}

/**
* @param {Date} date
*/
export function formatDateShortOrdinal(date) {
return !date ? '?' : shortAbbrNth(date) + nth(date.getDate());
}

export function formatDateISO(date) {
return !date ? '?' : iso(date);
}
Expand Down
7 changes: 7 additions & 0 deletions src/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,10 @@
@import './styles/vega.css';
@import './styles/tooltip.css';
@import './styles/uikit.css';

.grid-3-8 {
grid-column: 3 / 8;
}
.grid-8-11 {
grid-column: 8 / 11;
}
2 changes: 1 addition & 1 deletion src/maps/infos.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const nationInfo = {
level: 'nation',
name: 'US',
id: 'us',
displayName: 'US - Whole Nation',
displayName: 'United States',
propertyId: 'us',
population: stateInfo.reduce((acc, v) => acc + v.population, 0),
};
Expand Down
6 changes: 3 additions & 3 deletions src/modes/survey/Survey.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
}
.toc-container {
position: sticky;
top: 70px;
top: 100px;
margin-top: 1em;
}

Expand All @@ -45,16 +45,16 @@
</style>

<div class="root">
<SurveyParameters />
<div class="uk-container content-grid">
<div class="grid-3-11">
<Overview />
<h2>Results</h2>
</div>
<SurveyParameters />
<div class="grid-1-3">
<div class="toc-container uk-visible@m">
<div class="toc">
<h5>Outline</h5>
<h5>Survey questions</h5>
<ol uk-scrollspy-nav="closest: li; scroll: true; offset: 100" class="uk-nav uk-nav-default">
{#each questionCategories as cat}
<li><a href="#{cat.anchor}">{cat.name}</a></li>
Expand Down
57 changes: 25 additions & 32 deletions src/modes/survey/SurveyParameters.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,48 +15,41 @@
</script>

<style>
.parameters {
.parameter-container {
position: sticky;
top: -1px;
background: white;
z-index: 100;
padding-bottom: 0.5em;
display: flex;
box-shadow: 0 0 0 18px white; /* to hide box-shadow from cards */
top: 0px;
background: #fafafc;
border-top: 1px solid #d3d4d8;
border-bottom: 1px solid #d3d4d8;
z-index: 120;
}

.uk-container {
margin-top: 10px;
margin-bottom: 10px;
}

@media only screen and (max-width: 715px) {
.parameters {
display: block;
padding-bottom: 0;
}
.parameters > :global(*) {
margin-bottom: 0.5em;
}
}

.parameters :global(.survey-search) {
background: #f0f1f3;
flex: 2 1 auto;
}
.parameters :global(.survey-search input) {
background: #f0f1f3;
letter-spacing: 3px;
}

.parameters :global(.survey-date) {
flex: 1 1 auto;
}
</style>

<aside class="grid-3-11 parameters">
<Search
className="survey-search"
placeholder="Search Region"
items={filteredInfos}
selectedItem={$currentRegionInfo || nationInfo}
labelFieldName="displayName"
maxItemsToShowInList="5"
on:change={(e) => selectByInfo(e.detail && e.detail.level === 'nation' ? null : e.detail)} />
<SensorDatePicker2 className="survey-date" bind:value={selectedDate} sensor={refSensor} />
</aside>
<div class="parameter-container">
<div class="content-grid uk-container parameters">
<Search
className="survey-search grid-3-8"
modern
placeholder="Search Region"
items={filteredInfos}
selectedItem={$currentRegionInfo || nationInfo}
labelFieldName="displayName"
maxItemsToShowInList="5"
on:change={(e) => selectByInfo(e.detail && e.detail.level === 'nation' ? null : e.detail)} />
<SensorDatePicker2 className="survey-date grid-8-11" bind:value={selectedDate} sensor={refSensor} />
</div>
</div>