Skip to content

Commit

Permalink
Merge 577988d into 1445e47
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszjedrasik committed Jan 13, 2021
2 parents 1445e47 + 577988d commit 449a97f
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 8 deletions.
5 changes: 3 additions & 2 deletions packages/core/docs/general/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ Let's imagine you have some global components for error notifications. You want

```ts
const { cart, error } = useCart()
const { send } = useUiNotification();

watch(error, (error, prevError) => {
if (error.value.addItem && error.value.addItem !== prevError.value.addItem) sendInAppNotification('error', error.value.addItem.message)
if (error.value.removeItem && error.value.removeItem !== prevError.value.removeItem) sendInAppNotification('error', error.value.removeItem.message)
if (error.value.addItem && error.value.addItem !== prevError.value.addItem) send({ type: 'danger', message: error.value.addItem.message })
if (error.value.removeItem && error.value.removeItem !== prevError.value.removeItem) send({ type: 'danger', message: error.value.removeItem.message })
})
```
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@
</template>
</SfProperty>
<nuxt-link :to="`/checkout/${isAuthenticated ? 'shipping' : 'personal-details'}`">
<SfButton
class="sf-button--full-width color-secondary"
@click="toggleCartSidebar"
<SfButton
class="sf-button--full-width color-secondary"
@click="toggleCartSidebar"
>
{{ $t('Go to checkout') }}
</SfButton>
Expand All @@ -87,7 +87,7 @@
<SfButton
class="sf-button--full-width color-primary"
@click="toggleCartSidebar"
>{{ $t('Go back shopping') }}</SfButton
>{{ $t('Go back shopping') }}</SfButton
>
</div>
</transition>
Expand Down
105 changes: 105 additions & 0 deletions packages/core/nuxt-theme-module/theme/components/Notification.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<template>
<transition-group tag="div" class="notifications" :name="isMobile ? 'slide' : 'sf-fade'">
<SfNotification
v-for="notification in notifications"
:key="notification.id"
:visible="true"
:message="notification.message"
:action="notification.action && notification.action.text"
:type="notification.type"
@click:close="notification.dismiss()"
@click:action="notification.action && notification.action.onClick()"
>
<template #icon v-if="notification.icon">
<SfIcon :icon="notification.icon" color="white"/>
</template>
</SfNotification>
</transition-group>
</template>

<script>
import { SfNotification, SfIcon } from '@storefront-ui/vue';
import { useUiNotification } from '~/composables';
import { ref, onMounted, onBeforeUnmount} from '@vue/composition-api';
export default {
name: 'Notification',
components: {
SfNotification,
SfIcon
},
setup () {
const { notifications } = useUiNotification();
const isMobile = ref(false);
const mobileHandler = (event) => {
isMobile.value = event.matches;
};
onMounted(() => {
isMobile.value =
Math.max(document.documentElement.clientWidth, window.innerWidth) <=
1023;
window.matchMedia('(max-width: 1023px)').addListener(mobileHandler);
});
onBeforeUnmount(() => {
window
.matchMedia('(max-width: 1023px)')
.removeListener(mobileHandler);
});
return {
notifications,
isMobile
};
}
};
</script>

<style scoped lang="scss">
.notifications {
position: fixed;
width: 100%;
left: 0;
bottom: 0;
right: 0;
z-index: 9;
@include for-desktop {
top: 100px;
left: auto;
bottom: auto;
right: 5%;
width: 320px;
}
}
.sf-notification {
max-width: 100%;
margin: var(--spacer-xs) auto 0 auto;
&:first-child {
margin-top: 0;
}
@include for-mobile {
--notification-border-radius: 0;
--notification-max-width: 100%;
--notification-background: var(--c-link);
--notification-font-size: var(--font-size--sm);
--notification-font-family: var(--font-family--primary);
--notification-font-weight: var(--font-weight--normal);
--notification-padding: var(--spacer-base) var(--spacer-lg);
}
@include for-desktop {
margin: 0 0 var(--spacer-xs) 0;
}
}
.slide-enter-active,
.slide-leave-active {
transition: all 0.3s;
}
.slide-enter {
transform: translateY(40px);
}
.slide-leave-to {
transform: translateY(80px);
}
</style>
4 changes: 3 additions & 1 deletion packages/core/nuxt-theme-module/theme/composables/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import useUiHelpers from './useUiHelpers';
import useUiState from './useUiState';
import useUiNotification from './useUiNotification';

export {
useUiHelpers,
useUiState
useUiState,
useUiNotification
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { computed, reactive } from '@vue/composition-api';

interface UiNotification {
message: string;
action: { text: string; onClick: Function };
type: 'danger' | 'success' | 'info';
icon: string;
persist: boolean;
id: symbol;
dismiss: () => void;
}

interface Notifications {
notifications: Array<UiNotification>;
}

const state = reactive<Notifications>({
notifications: []
});

const useUiNotification = () => {
const send = (notification: UiNotification) => {
const id = Symbol();

const dismiss = () => {
const index = state.notifications.findIndex(notification => notification.id === id);

if (index !== -1) state.notifications.splice(index, 1);
};

const newNotification = {
...notification,
id,
dismiss
};

state.notifications.push(newNotification);
if (state.notifications.length > 3) state.notifications.shift();

if (!notification.persist) {
setTimeout(() => {
dismiss();
}, 3000);
}
};

return {
send,
notifications: computed(() => state.notifications)
};
};

export default useUiNotification;
5 changes: 4 additions & 1 deletion packages/core/nuxt-theme-module/theme/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<CartSidebar />
<WishlistSidebar />
<LoginModal />
<Notification />
</div>
</div>
</template>
Expand All @@ -35,6 +36,7 @@ import CartSidebar from '~/components/CartSidebar.vue';
import WishlistSidebar from '~/components/WishlistSidebar.vue';
import LoginModal from '~/components/LoginModal.vue';
import LazyHydrate from 'vue-lazy-hydration';
import Notification from '~/components/Notification';
export default {
components: {
Expand All @@ -45,7 +47,8 @@ export default {
AppFooter,
CartSidebar,
WishlistSidebar,
LoginModal
LoginModal,
Notification
}
};
</script>
Expand Down

0 comments on commit 449a97f

Please sign in to comment.