Skip to content

Commit

Permalink
Merge a97841c into ea2c90a
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszjedrasik committed Jan 19, 2021
2 parents ea2c90a + a97841c commit 2792420
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 8 deletions.
8 changes: 8 additions & 0 deletions packages/core/docs/changelog/5363.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
description: 'added useUiNotification composable',
link: 'https://github.com/vuestorefront/vue-storefront/issues/5363',
isBreaking: false,
breakingChanges: [],
author: 'Łukasz Jędrasik',
linkToGitHubAccount: 'https://github.com/lukaszjedrasik'
};
3 changes: 3 additions & 0 deletions packages/core/docs/contributing/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 2.3.0 (not relased)
- added useUiNotification composable ([#5363](https://github.com/vuestorefront/vue-storefront/issues/5363))

## 2.2.0
- added bottom margin to fix visibility of last footer category ([#5253](https://github.com/DivanteLtd/vue-storefront/issues/5253))
- [BREAKING] refactored names of many factory methods and composable methods, details in linked PR ([#5299](https://github.com/DivanteLtd/vue-storefront/pull/5299))
Expand Down
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
94 changes: 94 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,94 @@
<template>
<transition-group tag="div" class="notifications" name="slide-fade">
<SfNotification
v-for="notification in notifications"
:key="notification.id"
:message="notification.message"
:action="notification.action && notification.action.text"
:type="notification.type"
@click:close="notification.dismiss"
@click:action="notification.action && notification.action.onClick()"
visible
>
<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';

export default {
name: 'Notification',
components: {
SfNotification,
SfIcon
},
setup () {
const { notifications } = useUiNotification();

return {
notifications
};
}
};
</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-fade-enter-active,
.slide-fade-leave-active {
transition: all 0.3s;
@include for-desktop {
transition: opacity 0.25s linear;
}
}
.slide-fade-enter {
transform: translateY(40px);
@include for-desktop {
opacity: 0;
}
}
.slide-fade-leave-to {
transform: translateY(80px);
@include for-desktop {
opacity: 0;
}
}
</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 maxVisibleNotifications = 3;
const timeToLive = 3000;

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 > maxVisibleNotifications) state.notifications.shift();

if (!notification.persist) {
setTimeout(dismiss, timeToLive);
}
};

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 2792420

Please sign in to comment.