diff --git a/docs/app.vue b/docs/app.vue index 6a619bd..ddb8e1d 100644 --- a/docs/app.vue +++ b/docs/app.vue @@ -5,11 +5,11 @@ provide('navigation', navigation) diff --git a/src/runtime/components/overlays/Messages.vue b/src/runtime/components/overlays/Messages.vue index 19d82c2..be75dbb 100644 --- a/src/runtime/components/overlays/Messages.vue +++ b/src/runtime/components/overlays/Messages.vue @@ -1,20 +1,16 @@ - - diff --git a/src/runtime/composables/useMessage.ts b/src/runtime/composables/useMessage.ts index b648773..2d04002 100644 --- a/src/runtime/composables/useMessage.ts +++ b/src/runtime/composables/useMessage.ts @@ -1,10 +1,46 @@ -import { inject } from 'vue' -import type { MessageApi } from '../types/message' +import type { Message, MessageType } from '../types/message' +import { useState } from '#imports' export const useMessage = () => { - const message = inject('ray-message') - if (!message) { - throw new Error('No outer message-provider found!') + const messages = useState('messages', () => []) + + const add = (message: Partial) => { + const msg = { + id: (Date.now() + Math.random() * 100).toString(32).toUpperCase(), + duration: 3000, + ...message, + } + + if (messages.value.some(m => m.id === msg.id)) { + return + } + + messages.value.push(msg as Message) + return msg + } + + const update = (id: string, message: Partial) => { + const msg = messages.value.find(msg => msg.id === id) + + if (!msg) { + return + } + + Object.assign(msg, message) + } + + const remove = (id: string) => { + messages.value = messages.value.filter(msg => msg.id !== id) + } + + const clear = () => { + messages.value = [] + } + + return { + add, + update, + remove, + clear, } - return message } diff --git a/src/runtime/types/message.d.ts b/src/runtime/types/message.d.ts index fb443a5..ced692c 100644 --- a/src/runtime/types/message.d.ts +++ b/src/runtime/types/message.d.ts @@ -1,9 +1,14 @@ +import type { message } from '../ui.config' +import type colors from '#ray-colors' + export type MessageType = 'success' | 'warning' | 'error' | 'info' +export type MessageColor = (typeof colors)[number] export interface Message { id: string content: string type: MessageType + color?: MessageColor duration?: number } diff --git a/src/runtime/ui.config/index.ts b/src/runtime/ui.config/index.ts index e428d0c..3dd4b23 100644 --- a/src/runtime/ui.config/index.ts +++ b/src/runtime/ui.config/index.ts @@ -3,4 +3,4 @@ export { default as button } from './elements/button' // overlays export { default as message } from './overlays/message' -export { default as messages } from "./overlays/messages"; +export { default as messages } from './overlays/messages' diff --git a/src/runtime/ui.config/overlays/message.ts b/src/runtime/ui.config/overlays/message.ts index b1c6ea4..4dd734d 100644 --- a/src/runtime/ui.config/overlays/message.ts +++ b/src/runtime/ui.config/overlays/message.ts @@ -1 +1,12 @@ -export default {} +export default { + wrapper: 'mx-auto w-fit pointer-events-auto', + container: 'px-2 py-1.5 border flex items-center gap-1.5', + rounded: 'rounded-md', + border: 'border-{color}-400 dark:border-{color}-600', + background: 'bg-{color}-50 dark:bg-{color}-900', + content: 'text-xs font-sans font-bold text-{color}-500 dark:text-{color}-300', + default: { + color: 'primary', + duration: 4000, + }, +} diff --git a/src/runtime/ui.config/overlays/messages.ts b/src/runtime/ui.config/overlays/messages.ts index 993ac5c..3d40ebf 100644 --- a/src/runtime/ui.config/overlays/messages.ts +++ b/src/runtime/ui.config/overlays/messages.ts @@ -1,5 +1,14 @@ export default { - wrapper: "fixed flex flex-col w-full pointer-events-none z-[500]", - position: "bottom-0 end-0", - container: "px-4 sm:px-6 py-6 space-y-3 overflow-y-auto", -}; + wrapper: 'fixed flex flex-col z-[500] pointer-events-none', + position: 'start-0 end-0', + container: 'pt-2.5 flex flex-col items-center gap-2', + transition: { + moveClass: 'transform ease-out duration-300 transition', + enterActiveClass: 'transform ease-out duration-300 transition', + leaveActiveClass: 'transform ease-out duration-300 transition absolute', + enterFromClass: '-translate-y-2 opacity-0', + enterToClass: 'translate-y-0 opacity-100', + leaveFromClass: 'translate-y-0 opacity-100', + leaveToClass: '-translate-y-2 opacity-0', + }, +} diff --git a/src/runtime/utils/colors.ts b/src/runtime/utils/colors.ts index 01a1031..6e4a9ec 100644 --- a/src/runtime/utils/colors.ts +++ b/src/runtime/utils/colors.ts @@ -131,6 +131,29 @@ const safelistForComponent: Record< variants: ['focus-visible'], }, ], + message: colorsToRegex => [ + { + pattern: RegExp(`^bg-(${colorsToRegex})-50$`), + }, + { + pattern: RegExp(`^bg-(${colorsToRegex})-900$`), + variants: ['dark'], + }, + { + pattern: RegExp(`^text-(${colorsToRegex})-500$`), + }, + { + pattern: RegExp(`^text-(${colorsToRegex})-300$`), + variants: ['dark'], + }, + { + pattern: RegExp(`^border-(${colorsToRegex})-400$`), + }, + { + pattern: RegExp(`^border-(${colorsToRegex})-600$`), + variants: ['dark'], + }, + ], } export const generateSafelist = (colors: string[], globalColors: string[]) => {