feat: separate Base bubble

Also added a provider to inject local variant and orientation state to child components
This commit is contained in:
Shivam Mishra
2024-11-27 18:32:46 +05:30
parent 93bbcb2976
commit 0ae085ffbb
4 changed files with 73 additions and 49 deletions
@@ -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);
}