Skip to content

Commit

Permalink
feat(app): added theme
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewcourtice committed Aug 10, 2021
1 parent ca345e6 commit 84e6f64
Show file tree
Hide file tree
Showing 19 changed files with 99 additions and 33 deletions.
60 changes: 37 additions & 23 deletions app/src/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,27 @@
<br>
If you have the Vue <strong>devtools</strong> installed, open them up and change the inspector to Harlem to see the store. The source code for this demo is available <a href="https://github.com/andrewcourtice/harlem/tree/main/app" target="_blank">here</a>.
</p>
<choice-group class="app__theme">
<choice v-for="{ label, value } in state.themes" :key="value" :id="value" :value="value" v-model="theme">{{ label }}</choice>
</choice-group>
</header>
<div class="app__options" layout="rows center-justify">
<choice-group>
<choice v-for="{ label, value } in state.clockTypes" :key="value" :id="value" :value="value" v-model="clockType">
<span>{{ label }}</span>
</choice>
<choice v-for="{ label, value } in state.clockTypes" :key="value" :id="value" :value="value" v-model="clockType">{{ label }}</choice>
</choice-group>
<div layout="rows center-right" self="size-auto">
<button class="button button--primary" @click="openAddClockModal()">Add Clock</button>
</div>
</div>
<div class="clocks">
<div class="app__clocks">
<transition-group name="clocks">
<div class="clock" v-for="{ time, timezone } in clocks" :key="timezone">
<div class="app__clock" v-for="{ time, timezone } in clocks" :key="timezone">
<component :is="clockComponent" :time="time"></component>
<div class="clock__label">
<div class="clock__timezone">{{ timezone }}</div>
<div class="clock__date">{{ getClockDateLabel(time, timezone) }}</div>
<div class="app__clock-label">
<div class="app__clock-timezone">{{ getTimezoneLabel(timezone) }}</div>
<div class="app__clock-date">{{ getClockDateLabel(time, timezone) }}</div>
</div>
<div class="clock__shade" layout="row bottom-stretch">
<div class="app__clock-shade" layout="row bottom-stretch">
<button class="button button--alert" @click="removeClock(timezone)">Remove</button>
</div>
</div>
Expand All @@ -57,9 +58,12 @@ import AnalogueClock from './components/clocks/analogue-clock.vue';
import DigitalClock from './components/clocks/digital-clock.vue';
import AddClockModal from './components/modals/add-clock.vue'
import getTimezoneLabel from './utilities/time/get-timezone-label';
import {
computed,
ref,
watchEffect,
} from 'vue';
import {
Expand All @@ -71,15 +75,21 @@ import {
clocks,
setClockType,
removeClock,
undo,
redo,
loadTimezones
} from './stores/time';
loadTimezones,
setTheme,
} from './stores/app';
loadTimezones();
watchEffect(() => document.body.setAttribute('theme', state.theme.toLowerCase()));
const addClockModal = ref();
const theme = computed({
get: () => state.theme,
set: theme => setTheme(theme)
});
const clockType = computed({
get: () => state.clockType,
set: type => setClockType(type)
Expand Down Expand Up @@ -114,7 +124,7 @@ function openAddClockModal() {
}
.app__header {
border-bottom: 1px solid #EDEDED;
border-bottom: 1px solid var(--border__colour);
}
.app__logo {
Expand All @@ -128,11 +138,15 @@ function openAddClockModal() {
text-align: center;
}
.app__theme {
margin-top: 2rem;
}
.app__options {
margin: 2rem 0;
}
.clocks {
.app__clocks {
display: grid;
gap: 2rem;
grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
Expand All @@ -141,46 +155,46 @@ function openAddClockModal() {
align-items: stretch;
}
.clock {
.app__clock {
position: relative;
padding: 1.5rem;
text-align: center;
background-color: #EEE;
background-color: var(--foreground__colour);
border-radius: 1.5rem;
overflow: hidden;
&:hover {
& .clock__shade {
& .app__clock-shade {
display: flex;
animation: clock-shade var(--animation__timing) var(--animation__easing)
}
}
}
.clock__label {
.app__clock-label {
margin-top: 1.5rem;
}
.clock__timezone {
.app__clock-timezone {
font-weight: var(--font__weight--semi-bold);
}
.clock__date {
.app__clock-date {
margin-top: 0.25rem;
font-size: var(--font__size--meta);
color: var(--font__colour--meta)
}
.clock__shade {
.app__clock-shade {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 1.5rem;
background-color: rgba(0, 0, 0, 0.5);
background-color: var(--background__colour--shade);
}
.clocks-enter-from,
Expand Down
2 changes: 2 additions & 0 deletions app/src/assets/styles/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ body {
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
-moz-osx-font-smoothing: grayscale;
transition: color var(--animation__timing) var(--animation__easing),
background var(--animation__timing) var(--animation__easing);
}

a {
Expand Down
4 changes: 2 additions & 2 deletions app/src/assets/styles/_buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@

.button--alert {
color: var(--font__colour--inverse);
background-color: red;
background-color: var(--colour__alert);

&:hover {
background-color: red;
background-color: var(--colour__alert--dark);
}
}
1 change: 1 addition & 0 deletions app/src/assets/styles/_inputs.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
input[type="text"],
select,
textarea {
color: inherit;
font: inherit;
padding: 0.5rem 1rem;
background-color: var(--foreground__colour);
Expand Down
21 changes: 21 additions & 0 deletions app/src/assets/styles/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
--spacing__size: 16px;

--background__colour: #FFFFFF;
--background__colour--inverse: #333333;
--background__colour--shade: rgba(0, 0, 0, 0.5);

--foreground__colour: #EEEEEE;
--foreground__colour--dark: #DDDDDD;

Expand All @@ -26,7 +29,25 @@

--colour__primary: #76D1A7;
--colour__primary--dark: #66AB8B;
--colour__alert: #DC2626;
--colour__alert--dark: #B91C1C;

--border__colour: #EDEDED;

--animation__timing: 250ms;
--animation__easing: cubic-bezier(0.165, 0.84, 0.44, 1);
}

[theme="dark"] {
--background__colour: #333333;
--background__colour--inverse: #333333;
--background__colour--shade: rgba(0, 0, 0, 0.75);
--foreground__colour: #666666;
--foreground__colour--dark: #888888;

--font__colour: #EEEEEE;
--font__colour--meta: #CCCCCC;
--font__colour--inverse: #FFFFFF;

--border__colour: #666666;
}
6 changes: 3 additions & 3 deletions app/src/components/clocks/analogue-clock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const handStyles = computed(() => {
width: 100%;
aspect-ratio: 1 / 1;
padding: 0.75rem;
background-color: #000;
background-color: var(--background__colour--inverse);
border-radius: 50%;
}
Expand Down Expand Up @@ -100,7 +100,7 @@ const handStyles = computed(() => {
width: 6px;
height: 6px;
border-radius: 100%;
background-color: #76D1A7;
background-color: var(--colour__primary);
transform: translate(-50%, -50%);
}
Expand All @@ -118,7 +118,7 @@ const handStyles = computed(() => {
&::after {
height: 45%;
background-color: #76D1A7;
background-color: var(--colour__primary);
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/clocks/digital-clock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const labels = computed(() => ({
font-family: 'Digital', 'Open Sans';
padding: 1rem;
color: rgb(200, 200, 200);
background-color: #000;
background-color: var(--background__colour--inverse);
border-radius: 0.5rem;
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/components/core/choice.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ const choiceClass = computed(() => ({
display: inline-block;
padding: 0.75rem 2rem;
font-weight: var(--font__weight--semi-bold);
text-overflow: ellipsis;
white-space: nowrap;
border-radius: 0.5rem;
cursor: pointer;
transition: color var(--animation__timing) var(--animation__easing),
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/core/modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defineExpose({
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
background-color: var(--background__colour--shade);
z-index: 1000;
}
Expand Down
5 changes: 3 additions & 2 deletions app/src/components/modals/add-clock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<label class="form-label" for="">Timezone</label>
<input class="add-clock-modal__filter" v-model="model.filter" type="text" placeholder="Search for a timezone..." autofocus>
<select class="add-clock-modal__timezones" v-model="model.selection" multiple="true">
<option v-for="timezone in filteredTimezones" :key="timezone" :value="timezone">{{ timezone }}</option>
<option v-for="timezone in filteredTimezones" :key="timezone" :value="timezone">{{ getTimezoneLabel(timezone) }}</option>
</select>
<div class="add-clock-modal__tip">
<meta-text>
Expand All @@ -27,6 +27,7 @@ import Modal from '../core/modal.vue';
import MetaText from '../core/meta-text.vue';
import isEqual from '../../utilities/string/is-equal';
import getTimezoneLabel from '../../utilities/time/get-timezone-label';
import {
computed,
Expand All @@ -37,7 +38,7 @@ import {
import {
addClocks,
timezones
} from '../../stores/time';
} from '../../stores/app';
const modal = ref();
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import {

import type {
ClockType,
Theme,
} from './types';

export const setTheme = mutation('set-theme', (state, theme: Theme) => state.theme = theme);
export const updateTime = mutation('update-time', state => state.time = new Date());
export const setClockType = mutation('set-clock-type', (state, type: ClockType) => state.clockType = type);
export const addClocks = mutation('add-clocks', (state, timezones: string | string[]) => state.clocks = state.clocks.concat(timezones));
Expand Down
11 changes: 11 additions & 0 deletions app/src/stores/time/state.ts → app/src/stores/app/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ import type {
} from './types';

export default {
theme: 'light',
themes: [
{
label: 'Light',
value: 'light',
},
{
label: 'Dark',
value: 'dark',
},
],
time: new Date(),
timezones: [],
clockType: 'analogue',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const {
mutation,
action,
isActionRunning,
} = createStore('time', STATE, {
} = createStore('app', STATE, {
extensions: [
actionExtension(),
],
Expand Down
6 changes: 6 additions & 0 deletions app/src/stores/time/types.ts → app/src/stores/app/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export type Theme = 'light' | 'dark';
export type ClockType = 'analogue' | 'digital';

export interface Timezone {
Expand All @@ -10,6 +11,11 @@ export interface Timezone {
}

export interface State {
theme: Theme;
themes: {
label: string;
value: Theme;
}[];
time: Date;
timezones: Timezone[];
clockType: ClockType;
Expand Down
3 changes: 3 additions & 0 deletions app/src/utilities/string/capitalise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function capitalise(value: string): string {
return value.replace(/^(.)|\s+(.)/g, char => char.toUpperCase());
}
3 changes: 3 additions & 0 deletions app/src/utilities/time/get-timezone-label.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function getTimezoneLabel(timezone: string): string {
return (timezone.split('/').pop() ?? '')?.replace('_', ' ') ?? timezone;
}

0 comments on commit 84e6f64

Please sign in to comment.