Skip to content

Commit

Permalink
fix(VsToast): add primary & style-set (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
smithoo authored Sep 23, 2024
1 parent 61451f6 commit 8c5f320
Show file tree
Hide file tree
Showing 20 changed files with 291 additions and 544 deletions.
2 changes: 2 additions & 0 deletions packages/vlossom/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,7 @@ export { default as VsTextarea } from './vs-textarea/VsTextarea.vue';
export { type VsThemeButtonStyleSet } from './vs-theme-button/types';
export { default as VsThemeButton } from './vs-theme-button/VsThemeButton.vue';

export { type VsToastStyleSet } from './vs-toast/types';

export { type VsTooltipStyleSet } from './vs-tooltip/types';
export { default as VsTooltip } from './vs-tooltip/VsTooltip.vue';
4 changes: 2 additions & 2 deletions packages/vlossom/src/components/vs-drawer/VsDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ export default defineComponent({
focusLock: { type: Boolean, default: true },
hideScroll: { type: Boolean, default: false },
initialFocusRef: {
type: [Object, undefined] as PropType<HTMLElement | null>,
type: Object as PropType<HTMLElement | null>,
default: null,
},
open: { type: Boolean, default: false },
placement: {
type: String as PropType<Placement>,
type: String as PropType<Exclude<Placement, 'middle'>>,
default: 'left',
validator: (val: Placement) => utils.props.checkPropExist<Placement>(name, 'placement', PLACEMENTS, val),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default defineComponent({
name: VsComponent.VsFocusTrap,
props: {
focusLock: { type: Boolean, default: true },
initialFocusRef: { type: [Object, undefined] as PropType<HTMLElement | null>, default: null },
initialFocusRef: { type: Object as PropType<HTMLElement | null>, default: null },
},
setup(props, { slots, expose }) {
const { focusLock, initialFocusRef } = toRefs(props);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default defineComponent({
link: { type: String, default: '' },
noTooltip: { type: Boolean, default: false },
placement: {
type: String as PropType<Placement>,
type: String as PropType<Exclude<Placement, 'middle'>>,
default: 'top',
validator: (val: Placement) => utils.props.checkPropExist<Placement>(name, 'placement', PLACEMENTS, val),
},
Expand Down
41 changes: 23 additions & 18 deletions packages/vlossom/src/components/vs-toast/VsToast.scss
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
.vs-toast {
position: relative;
background-color: var(--vs-comp-bg);
color: var(--vs-comp-font);
border: 1px solid var(--vs-line-color);
display: flex;
justify-content: center;
border-radius: calc(var(--vs-radius-ratio) * var(--vs-radius-lg));
font-size: var(--vs-font-size);
align-items: center;
background-color: var(--vs-toast-backgroundColor, var(--vs-comp-bg));
color: var(--vs-toast-fontColor, var(--vs-comp-font));
border: var(--vs-toast-border, 1px solid var(--vs-line-color));
border-radius: var(--vs-toast-borderRadius, calc(var(--vs-radius-ratio) * var(--vs-radius-lg)));
font-size: var(--vs-toast-fontSize, var(--vs-font-size));
font-weight: var(--vs-toast-fontWeight, 400);
margin: 0.4rem 0;
pointer-events: auto;
width: fit-content;

.vs-toast-contents {
.vs-toast-content {
position: relative;
padding: 1rem 5rem;
padding: var(--vs-toast-padding, 1rem 5rem);
}

.vs-toast-close {
position: absolute;
top: 0.3rem;
right: 0.3rem;
top: 50%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
border-radius: calc(var(--vs-radius-ratio) * var(--vs-radius));
color: var(--vs-comp-font);
padding: 0.2rem;
align-items: center;
right: 0.5rem;
height: 20px;
width: 20px;
color: var(--vs-toast-fontColor, var(--vs-comp-font));
}

&:hover {
background-color: var(--vs-comp-bg-hover);
}
&.vs-primary {
background-color: var(--vs-toast-backgroundColor, var(--vs-primary-comp-bg));
color: var(--vs-toast-fontColor, var(--vs-primary-comp-font));
border: var(--vs-toast-border, 1px solid var(--vs-primary-comp-bg));

&:active {
background-color: var(--vs-comp-bg-active);
.vs-toast-close {
color: var(--vs-toast-fontColor, var(--vs-primary-comp-font));
}
}
}
89 changes: 20 additions & 69 deletions packages/vlossom/src/components/vs-toast/VsToast.vue
Original file line number Diff line number Diff line change
@@ -1,99 +1,50 @@
<template>
<div :class="['vs-toast', `vs-${getColorScheme()}`]" :style="computedStyle" role="alert">
<div class="vs-toast-contents">
<span v-html="toastInfo.text" />
<div :class="['vs-toast', colorSchemeClass, { 'vs-primary': primary }]" :style="computedStyleSet" role="alert">
<div class="vs-toast-content">
<span v-html="content" />
</div>
<button
class="vs-toast-close"
type="button"
ref="closeButtonRef"
v-if="!toastInfo.autoClose"
@click.stop="closeToast"
aria-label="close"
>
<button v-if="!autoClose" class="vs-toast-close" type="button" @click.stop="closeToast" aria-label="close">
<vs-icon icon="close" size="14px" />
</button>
</div>
</template>

<script lang="ts">
import { PropType, computed, defineComponent, ref, toRef, toRefs } from 'vue';
import { UIState } from '@/declaration';
import { useColorScheme } from '@/composables';
import { PropType, defineComponent, toRefs } from 'vue';
import { ColorScheme } from '@/declaration';
import { useColorScheme, useStyleSet } from '@/composables';
import { VsIcon } from '@/icons';
import { store } from '@/stores';
import { VsComponent } from '@/declaration';
import type { ToastInfo } from '@/plugins';
import type { VsToastStyleSet } from './types';
const name = VsComponent.VsToast;
export default defineComponent({
name,
components: { VsIcon },
props: {
toastInfo: { type: Object as PropType<ToastInfo>, required: true },
id: { type: String, required: true },
content: { type: String, required: true },
colorScheme: { type: String as PropType<ColorScheme> },
styleSet: { type: [String, Object] as PropType<string | VsToastStyleSet> },
autoClose: { type: Boolean, default: true },
primary: { type: Boolean, default: false },
},
setup(props) {
const { toastInfo } = toRefs(props);
const closeButtonRef = ref(null);
const { id, colorScheme, styleSet } = toRefs(props);
function getColorScheme() {
let color = 'default';
if (toastInfo.value.state) {
switch (toastInfo.value.state) {
case UIState.Success:
color = 'green';
break;
case UIState.Info:
color = 'light-blue';
break;
case UIState.Error:
color = 'red';
break;
case UIState.Warning:
color = 'orange';
break;
default:
color = 'indigo';
break;
}
}
const { colorSchemeClass } = useColorScheme(name, colorScheme);
if (toastInfo.value.colorScheme) {
const { computedColorScheme } = useColorScheme(name, toRef(toastInfo.value.colorScheme));
color = computedColorScheme.value;
}
return color;
}
const computedStyle = computed(() => {
const style: { [key: string]: any } = {};
switch (toastInfo.value.align) {
case 'start':
style.alignSelf = 'flex-start';
break;
case 'center':
style.alignSelf = 'center';
break;
case 'end':
style.alignSelf = 'flex-end';
break;
default:
style.alignSelf = 'center';
break;
}
return style;
});
const { computedStyleSet } = useStyleSet<VsToastStyleSet>(name, styleSet);
function closeToast() {
store.toast.removeToast(toastInfo.value.id);
store.toast.removeToastById(id.value);
}
return {
closeButtonRef,
getColorScheme,
computedStyle,
colorSchemeClass,
computedStyleSet,
closeToast,
};
},
Expand Down
32 changes: 23 additions & 9 deletions packages/vlossom/src/components/vs-toast/VsToastView.scss
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
.vs-toast-view {
align-items: center;
position: fixed;
display: flex;
flex-direction: column;
pointer-events: none;
position: fixed;
transition: all 0.5s ease;
width: 98%;
width: 100%;
z-index: var(--vs-toast-z-index);

&.vs-top {
left: 50%;
&.vs-toast-view-top {
top: 3%;
transform: translateX(-50%);
}

&.vs-bottom {
&.vs-toast-view-middle {
top: 50%;
transform: translateY(-50%);
}

&.vs-toast-view-bottom {
bottom: 3%;
left: 50%;
transform: translateX(-50%);
}

&.vs-toast-view-start {
left: 1%;
align-items: flex-start;
}

&.vs-toast-view-center {
align-items: center;
}

&.vs-toast-view-end {
right: 1%;
align-items: flex-end;
}
}

Expand Down
25 changes: 15 additions & 10 deletions packages/vlossom/src/components/vs-toast/VsToastView.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
<template>
<div :class="['vs-toast-view', `vs-${placement}`, `vs-toast-view-${placement}`]">
<div :class="['vs-toast-view', `vs-toast-view-${placement}`, `vs-toast-view-${align}`]">
<TransitionGroup name="fade" appear>
<vs-toast ref="toastRefs" v-for="toast in toasts" :key="toast.id" :toastInfo="toast" />
<vs-toast
v-for="toast in toasts"
:key="toast.id"
:id="toast.id"
:content="toast.content"
:color-scheme="toast.colorScheme"
:style-set="toast.styleSet"
:auto-close="toast.autoClose"
:primary="toast.primary"
/>
</TransitionGroup>
</div>
</template>

<script lang="ts">
import { computed, defineComponent, toRefs, shallowRef, type PropType, type ShallowRef } from 'vue';
import { computed, defineComponent, toRefs, type PropType } from 'vue';
import { store } from '@/stores';
import VsToast from './VsToast.vue';
import { VsComponent } from '@/declaration';
import VsToast from './VsToast.vue';
import type { Placement, Align } from '@/declaration';
import type { ToastInfo } from '@/plugins';
Expand All @@ -25,18 +34,14 @@ export default defineComponent({
},
setup(props) {
const { placement, align } = toRefs(props);
const toasts = computed(() => {
return store.toast.toasts.filter(
(toast: ToastInfo) => toast.placement === placement.value && toast.align === align.value,
);
});
const toastRefs: ShallowRef<(typeof VsToast)[]> = shallowRef([]);
return {
toasts,
toastRefs,
};
return { toasts };
},
});
</script>
Expand Down
Loading

0 comments on commit 8c5f320

Please sign in to comment.