feat: separate Base bubble
Also added a provider to inject local variant and orientation state to child components
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { provideMessageContext } from './provider.js';
|
||||
import {
|
||||
MESSAGE_TYPES,
|
||||
MESSAGE_VARIANTS,
|
||||
@@ -186,6 +186,12 @@ const shouldShowAvatar = computed(() => {
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
provideMessageContext({
|
||||
variant,
|
||||
orientation,
|
||||
isMyMessage,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -210,12 +216,7 @@ const shouldShowAvatar = computed(() => {
|
||||
>
|
||||
<Avatar :name="sender ? sender.name : ''" src="" :size="24" />
|
||||
</div>
|
||||
<TextBubble
|
||||
v-bind="props"
|
||||
:variant
|
||||
:orientation
|
||||
class="[grid-area:bubble]"
|
||||
/>
|
||||
<TextBubble v-bind="props" class="[grid-area:bubble]" />
|
||||
<MessageError
|
||||
v-if="contentAttributes.externalError"
|
||||
class="[grid-area:meta]"
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useMessageContext } from '../provider.js';
|
||||
import { MESSAGE_VARIANTS } from '../constants';
|
||||
|
||||
const { variant, orientation } = useMessageContext();
|
||||
|
||||
const varaintBaseMap = {
|
||||
[MESSAGE_VARIANTS.AGENT]: 'bg-n-solid-blue p-3 text-n-slate-12',
|
||||
[MESSAGE_VARIANTS.PRIVATE]: 'bg-n-solid-amber p-3 text-n-amber-12',
|
||||
[MESSAGE_VARIANTS.USER]: 'bg-n-slate-4 p-3 text-n-slate-12',
|
||||
[MESSAGE_VARIANTS.ACTIVITY]:
|
||||
'bg-n-alpha-1 px-2 py-0.5 text-n-slate-11 text-sm',
|
||||
[MESSAGE_VARIANTS.BOT]: 'bg-n-teal-5 p-3 text-n-slate-12',
|
||||
[MESSAGE_VARIANTS.TEMPLATE]: 'bg-n-teal-5 p-3 text-n-slate-12',
|
||||
[MESSAGE_VARIANTS.ERROR]: 'bg-n-ruby-4 p-3 text-n-ruby-12',
|
||||
};
|
||||
|
||||
const orientationMap = {
|
||||
left: 'rounded-xl rounded-bl-sm',
|
||||
right: 'rounded-xl rounded-br-sm',
|
||||
center: 'rounded-md',
|
||||
};
|
||||
|
||||
const messageClass = computed(() => {
|
||||
const classToApply = [varaintBaseMap[variant.value]];
|
||||
|
||||
if (variant.value !== MESSAGE_VARIANTS.ACTIVITY) {
|
||||
classToApply.push(orientationMap[orientation.value]);
|
||||
} else {
|
||||
classToApply.push('rounded-lg');
|
||||
}
|
||||
|
||||
return classToApply;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="max-w-md text-sm" :class="messageClass">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,56 +1,21 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import MessageFormatter from 'shared/helpers/MessageFormatter.js';
|
||||
import { MESSAGE_VARIANTS, ORIENTATION } from '../constants';
|
||||
import BaseBubble from './Base.vue';
|
||||
import { useMessageContext } from '../provider.js';
|
||||
import { MESSAGE_VARIANTS } from '../constants';
|
||||
|
||||
const props = defineProps({
|
||||
variant: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: value => Object.values(MESSAGE_VARIANTS).includes(value),
|
||||
},
|
||||
orientation: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: value => Object.values(ORIENTATION).includes(value),
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const varaintBaseMap = {
|
||||
[MESSAGE_VARIANTS.AGENT]: 'bg-n-solid-blue p-3 text-n-slate-12',
|
||||
[MESSAGE_VARIANTS.PRIVATE]: 'bg-n-solid-amber p-3 text-n-amber-12',
|
||||
[MESSAGE_VARIANTS.USER]: 'bg-n-slate-4 p-3 text-n-slate-12',
|
||||
[MESSAGE_VARIANTS.ACTIVITY]:
|
||||
'bg-n-alpha-1 px-2 py-0.5 text-n-slate-11 text-sm',
|
||||
[MESSAGE_VARIANTS.BOT]: 'bg-n-teal-5 p-3 text-n-slate-12',
|
||||
[MESSAGE_VARIANTS.TEMPLATE]: 'bg-n-teal-5 p-3 text-n-slate-12',
|
||||
[MESSAGE_VARIANTS.ERROR]: 'bg-n-ruby-4 p-3 text-n-ruby-12',
|
||||
};
|
||||
|
||||
const orientationMap = {
|
||||
left: 'rounded-xl rounded-bl-sm',
|
||||
right: 'rounded-xl rounded-br-sm',
|
||||
center: 'rounded-md',
|
||||
};
|
||||
|
||||
const messageClass = computed(() => {
|
||||
const classToApply = [varaintBaseMap[props.variant]];
|
||||
|
||||
if (props.variant !== MESSAGE_VARIANTS.ACTIVITY) {
|
||||
classToApply.push(orientationMap[props.orientation]);
|
||||
} else {
|
||||
classToApply.push('rounded-lg');
|
||||
}
|
||||
|
||||
return classToApply;
|
||||
});
|
||||
const { variant } = useMessageContext();
|
||||
|
||||
const formattedContent = computed(() => {
|
||||
if (props.variant === MESSAGE_VARIANTS.ACTIVITY) {
|
||||
if (variant.value === MESSAGE_VARIANTS.ACTIVITY) {
|
||||
return props.content;
|
||||
}
|
||||
|
||||
@@ -59,9 +24,9 @@ const formattedContent = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="max-w-md text-sm" :class="messageClass">
|
||||
<BaseBubble>
|
||||
<span v-html="formattedContent" />
|
||||
</div>
|
||||
</BaseBubble>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { inject, provide } from 'vue';
|
||||
|
||||
const MessageControl = Symbol('MessageControl');
|
||||
|
||||
export function useMessageContext() {
|
||||
const context = inject(MessageControl, null);
|
||||
if (context === null) {
|
||||
throw new Error(`Component is missing a parent <Message /> component.`);
|
||||
}
|
||||
|
||||
return { ...context };
|
||||
}
|
||||
|
||||
export function provideMessageContext(context) {
|
||||
provide(MessageControl, context);
|
||||
}
|
||||
Reference in New Issue
Block a user