diff --git a/ui/dev/src/pages/components/chat.vue b/ui/dev/src/pages/components/chat.vue index f75329ad9d2..d671d2c2100 100644 --- a/ui/dev/src/pages/components/chat.vue +++ b/ui/dev/src/pages/components/chat.vue @@ -123,8 +123,10 @@ export default { }, { name: 'Jane', - text: [ 'And you?' ], + text: [ 'And you?', 'This bg color is #497ef2ff' ], sent: true, + bgColor: '#497ef2ff', + textColor: '#e4f7f6', avatar: 'https://cdn.quasar.dev/img/linux-avatar.png', stamp: 'Yesterday at 13:51' }, @@ -133,7 +135,9 @@ export default { }, { name: 'Vladimir', - text: [ 'Fine. Nice weather today, right?', 'Hmm...' ], + text: [ 'Fine. Nice weather today, right?', 'Hmm...', 'This bg color is rgba(176,76,176,0.8), and text color is #f2d3f2ff' ], + bgColor: 'rgba(176,76,176,0.8)', + textColor: '#f2d3f2ff', avatar: 'https://cdn.quasar.dev/img/boy-avatar.png', stamp: '13:55' }, @@ -143,7 +147,9 @@ export default { }, { name: 'Vladimir', - text: [ 'How are you?' ], + text: [ 'How are you?', 'This bg color is secondary, and text color is accent' ], + bgColor: 'secondary', + textColor: 'accent', avatar: 'https://cdn.quasar.dev/img/boy-avatar.png', stamp: 'Yesterday 13:34' }, diff --git a/ui/src/components/chat/QChatMessage.js b/ui/src/components/chat/QChatMessage.js index 3b9352265a6..2f581643120 100644 --- a/ui/src/components/chat/QChatMessage.js +++ b/ui/src/components/chat/QChatMessage.js @@ -1,7 +1,8 @@ -import { h, computed } from 'vue' +import { h, computed, toRef } from 'vue' import { createComponent } from '../../utils/private/create.js' import { getNormalizedVNodes } from '../../utils/private/vm.js' +import { useTextColor } from '../../composables/private/use-color.js' export default createComponent({ name: 'QChatMessage', @@ -25,15 +26,22 @@ export default createComponent({ setup (props, { slots }) { const op = computed(() => (props.sent === true ? 'sent' : 'received')) + const { textColorClasses: backgroundColorClasses, textColorStyles: backgroundColorStyles } = useTextColor(toRef(props, 'bgColor')) + const { textColorClasses, textColorStyles } = useTextColor(toRef(props, 'textColor')) + const textClass = computed(() => - `q-message-text-content q-message-text-content--${ op.value }` - + (props.textColor !== void 0 ? ` text-${ props.textColor }` : '') + `q-message-text-content q-message-text-content--${ op.value } ${ textColorClasses.value }` ) + const textStyle = computed(() => ({ + ...textColorStyles.value + })) const messageClass = computed(() => - `q-message-text q-message-text--${ op.value }` - + (props.bgColor !== void 0 ? ` text-${ props.bgColor }` : '') + `q-message-text q-message-text--${ op.value } ${ backgroundColorClasses.value }` ) + const messageStyle = computed(() => ({ + ...backgroundColorStyles.value + })) const containerClass = computed(() => 'q-message-container row items-end no-wrap' @@ -74,9 +82,10 @@ export default createComponent({ return contentList.map((msg, index) => h('div', { key: index, - class: messageClass.value + class: messageClass.value, + style: messageStyle.value }, [ - h('div', { class: textClass.value }, wrapStamp(content(msg))) + h('div', { class: textClass.value, style: textStyle.value }, wrapStamp(content(msg))) ])) } diff --git a/ui/src/composables/private/use-color.js b/ui/src/composables/private/use-color.js new file mode 100644 index 00000000000..941e0be9499 --- /dev/null +++ b/ui/src/composables/private/use-color.js @@ -0,0 +1,67 @@ +import { computed, reactive, isRef, watchEffect, toRefs } from 'vue' +import { isCssColor } from '../../utils/colors' + +export function destructComputed (getter) { + const refs = reactive({}) + const base = computed(getter) + watchEffect(() => { + for (const key in base.value) { + refs[ key ] = base.value[ key ] + } + }, { flush: 'sync' }) + return toRefs(refs) +} + +export function useColor (colors) { + return destructComputed(() => { + const classes = [] + const styles = {} + + if (colors.value.background) { + if (isCssColor(colors.value.background)) { + styles.backgroundColor = colors.value.background + } + else { + classes.push(`bg-${ colors.value.background }`) + } + } + + if (colors.value.text) { + if (isCssColor(colors.value.text)) { + styles.color = colors.value.text + styles.caretColor = colors.value.text + } + else { + classes.push(`text-${ colors.value.text }`) + } + } + + return { colorClasses: classes, colorStyles: styles } + }) +} + +export function useTextColor (props, name) { + const colors = computed(() => ({ + text: isRef(props) ? props.value : (name ? props[ name ] : null) + })) + + const { + colorClasses: textColorClasses, + colorStyles: textColorStyles + } = useColor(colors) + + return { textColorClasses, textColorStyles } +} + +export function useBackgroundColor (props, name) { + const colors = computed(() => ({ + background: isRef(props) ? props.value : (name ? props[ name ] : null) + })) + + const { + colorClasses: backgroundColorClasses, + colorStyles: backgroundColorStyles + } = useColor(colors) + + return { backgroundColorClasses, backgroundColorStyles } +} diff --git a/ui/src/utils/colors.js b/ui/src/utils/colors.js index 65a4a1ea378..96b0b74605f 100644 --- a/ui/src/utils/colors.js +++ b/ui/src/utils/colors.js @@ -280,6 +280,10 @@ export function getPaletteColor (colorName) { return rgbToHex(textToRgb(result)) } +export function isCssColor (color){ + return !!color && /^(#|var\(--|(rgb|hsl)a?\()/.test(color) +} + export default { rgbToHex, hexToRgb, @@ -291,5 +295,6 @@ export default { brightness, blend, changeAlpha, - getPaletteColor + getPaletteColor, + isCssColor }