Merge branch 'message' into 'main'
Message See merge request cellule-financiere-pmo/design-system/visua-vue!9
This commit is contained in:
commit
9da0952de8
|
@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.0.9] - 2025-07-24
|
||||||
|
### Added
|
||||||
|
- Message component
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Badge compoent icon
|
||||||
|
|
||||||
## [1.0.8] - 2025-07-23
|
## [1.0.8] - 2025-07-23
|
||||||
### Added
|
### Added
|
||||||
- ProgressBar component
|
- ProgressBar component
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# visua-vue
|
# visua-vue
|
||||||
|
|
||||||
**Current version: v1.0.8**
|
**Current version: v1.0.9**
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@cellule-financiere-pmo/visua-vue",
|
"name": "@cellule-financiere-pmo/visua-vue",
|
||||||
"version": "1.0.8",
|
"version": "1.0.9",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@cellule-financiere-pmo/visua-vue",
|
"name": "@cellule-financiere-pmo/visua-vue",
|
||||||
"version": "1.0.8",
|
"version": "1.0.9",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cellule-financiere-pmo/visua": "1.1.3",
|
"@cellule-financiere-pmo/visua": "1.1.3",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@cellule-financiere-pmo/visua-vue",
|
"name": "@cellule-financiere-pmo/visua-vue",
|
||||||
"version": "1.0.8",
|
"version": "1.0.9",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|
20
src/App.vue
20
src/App.vue
|
@ -5,20 +5,22 @@
|
||||||
// import VAccordionView from '../template/VAccordionView.vue';
|
// import VAccordionView from '../template/VAccordionView.vue';
|
||||||
// import VInputView from '../template/VInputView.vue';
|
// import VInputView from '../template/VInputView.vue';
|
||||||
// import VCheckboxView from '../template/VCheckboxView.vue';
|
// import VCheckboxView from '../template/VCheckboxView.vue';
|
||||||
// import VBadgeView from '../template/VBadgeView.vue';
|
import VBadgeView from '../template/VBadgeView.vue';
|
||||||
// import VSelectView from '../template/VSelectView.vue';
|
import VSelectView from '../template/VSelectView.vue';
|
||||||
import VProgressBarView from '../template/VProgressBarView.vue';
|
// import VProgressBarView from '../template/VProgressBarView.vue';
|
||||||
|
import VMessageView from '../template/VMessageView.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- <VButtonView/> -->
|
<!-- <VButtonView/> -->
|
||||||
<!-- <VButtonGroupView/> -->
|
<!-- <VButtonGroupView/> -->
|
||||||
<!-- <VLinkView/> -->
|
<!-- <VLinkView/> -->
|
||||||
<!-- <VAccordionView/> -->
|
<!-- <VAccordionView/> -->
|
||||||
<!-- <VInputView/> -->
|
<!-- <VInputView/> -->
|
||||||
<!-- <VCheckboxView/> -->
|
<!-- <VCheckboxView/> -->
|
||||||
<!-- <VBadgeView/> -->
|
<VBadgeView/>
|
||||||
<!-- <VSelectView/> -->
|
<VSelectView/>
|
||||||
<VProgressBarView/>
|
<!-- <VProgressBarView/> -->
|
||||||
|
<VMessageView/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -23,11 +23,11 @@ const severity = computed(() => {
|
||||||
|
|
||||||
const icon = computed(() => {
|
const icon = computed(() => {
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
case 'error': return 'ri-close-circle-line';
|
case 'error': return 'ri-spam-fill';
|
||||||
case 'warning' : return 'ri-alert-line';
|
case 'warning' : return 'ri-alert-fill';
|
||||||
case 'success' : return 'ri-checkbox-circle-line';
|
case 'success' : return 'ri-checkbox-circle-fill';
|
||||||
case 'info': return 'ri-information-line';
|
case 'info': return 'ri-information-fill';
|
||||||
case 'new': return 'ri-flashlight-line';
|
case 'new': return 'ri-flashlight-fill';
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ const limit = computed(() => props.maxWidth);
|
||||||
class="p-tag"
|
class="p-tag"
|
||||||
:class="{'small': props.small}"
|
:class="{'small': props.small}"
|
||||||
>
|
>
|
||||||
<i v-if="!props.noIcon || props.type === undefined" :class="icon"></i>
|
<i v-if="!props.noIcon || props.type === undefined" :class="icon" style="font-weight: 100;"></i>
|
||||||
<span :class="{'limit': props.maxWidth}">{{ props.label }}</span>
|
<span :class="{'limit': props.maxWidth}">{{ props.label }}</span>
|
||||||
</Tag>
|
</Tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
25
src/components/message/IVMessage.type.ts
Normal file
25
src/components/message/IVMessage.type.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* Interface representing the structure of a message notice component.
|
||||||
|
*/
|
||||||
|
export default interface IVMessage {
|
||||||
|
/**
|
||||||
|
* The title or main text of the notice.
|
||||||
|
*/
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of notice, which affects its visual style and semantics.
|
||||||
|
* - `info`: Informational message
|
||||||
|
* - `warning`: Warning message
|
||||||
|
* - `alert`: Error or critical alert
|
||||||
|
* - `success`: Confirmation or success message
|
||||||
|
* - undefined: No specific type
|
||||||
|
*/
|
||||||
|
type?: 'info' | 'warning' | 'alert' | 'success' | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, the notice can be closed by the user.
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
closable?: boolean;
|
||||||
|
}
|
115
src/components/message/VMessage.vue
Normal file
115
src/components/message/VMessage.vue
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type IVMessage from './IVMessage.type';
|
||||||
|
import Message from 'primevue/message';
|
||||||
|
import VButton from '../button/VButton.vue';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import styles from '@visua/typography.module.css';
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<IVMessage>(), {
|
||||||
|
type: undefined,
|
||||||
|
closable: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
|
const iconClass = computed(() => {
|
||||||
|
switch (props.type) {
|
||||||
|
case 'alert': return 'ri-spam-fill';
|
||||||
|
case 'warning' : return 'ri-alert-fill';
|
||||||
|
case 'success' : return 'ri-checkbox-circle-fill';
|
||||||
|
case 'info': return 'ri-information-fill';
|
||||||
|
default:
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const severity = computed(() => {
|
||||||
|
switch (props.type) {
|
||||||
|
case 'alert': return 'error';
|
||||||
|
case 'warning' : return 'warn';
|
||||||
|
case 'success' : return 'success';
|
||||||
|
case 'info' : return 'info';
|
||||||
|
default:
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const iconColor = computed(() => {
|
||||||
|
switch (props.type) {
|
||||||
|
case 'alert': return 'var(--text-default-error)';
|
||||||
|
case 'warning' : return 'var(--text-default-warning)';
|
||||||
|
case 'success' : return 'var(--text-default-success)';
|
||||||
|
case 'info': return 'var(--text-default-info)';
|
||||||
|
default:
|
||||||
|
return 'var(--text-mention-grey)';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Message
|
||||||
|
role="alert"
|
||||||
|
:closable="props.closable"
|
||||||
|
:severity="severity"
|
||||||
|
size="large"
|
||||||
|
class="p-message"
|
||||||
|
@close="emit('close', $event)"
|
||||||
|
>
|
||||||
|
<template #container="slotProps">
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<i :class="[iconClass]" :style="{color: iconColor}" style="font-size: var(--p-message-icon-lg-size);"></i>
|
||||||
|
<span class="title" :class="[styles['text-body-MD-standard-text-Regular']]" :style="{color: iconColor}">
|
||||||
|
{{ props.title }}
|
||||||
|
</span>
|
||||||
|
<VButton
|
||||||
|
v-if="props.closable"
|
||||||
|
title="Fermer le message"
|
||||||
|
tertiary
|
||||||
|
no-outline
|
||||||
|
size="sm"
|
||||||
|
icon-only
|
||||||
|
aria-label="Fermer"
|
||||||
|
icon="ri-close-line"
|
||||||
|
type="button"
|
||||||
|
@click="slotProps.closeCallback"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-if="$slots.content" class="content">
|
||||||
|
<slot name="content"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Message>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.p-message{
|
||||||
|
width: 100%;
|
||||||
|
height: fit-content;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container{
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--p-message-content-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: var(--p-message-content-gap);
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content{
|
||||||
|
display: block;
|
||||||
|
padding: 0rem 0.825rem 0.5rem 0.825rem;
|
||||||
|
}
|
||||||
|
</style>
|
37
test/VMessage.spec.ts
Normal file
37
test/VMessage.spec.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { describe, it, expect } from 'vitest'
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import VMessage from '../src/components/message/VMessage.vue'
|
||||||
|
|
||||||
|
describe('VMessage.vue', () => {
|
||||||
|
it('renders the title', () => {
|
||||||
|
const wrapper = mount(VMessage, {
|
||||||
|
props: { title: 'Test Message' }
|
||||||
|
})
|
||||||
|
expect(wrapper.text()).toContain('Test Message')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows the correct icon class for type "alert"', () => {
|
||||||
|
const wrapper = mount(VMessage, {
|
||||||
|
props: { title: 'Alert Message', type: 'alert' }
|
||||||
|
})
|
||||||
|
const icon = wrapper.find('i')
|
||||||
|
expect(icon.classes()).toContain('ri-spam-fill')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows the close button if closable is true', () => {
|
||||||
|
const wrapper = mount(VMessage, {
|
||||||
|
props: { title: 'Closable Message', closable: true }
|
||||||
|
})
|
||||||
|
const button = wrapper.find('button[aria-label="Fermer"]')
|
||||||
|
expect(button.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('emits close event when close button is clicked', async () => {
|
||||||
|
const wrapper = mount(VMessage, {
|
||||||
|
props: { title: 'Closable Message', closable: true }
|
||||||
|
})
|
||||||
|
const button = wrapper.find('button[aria-label="Fermer"]')
|
||||||
|
await button.trigger('click')
|
||||||
|
expect(wrapper.emitted()).toHaveProperty('close')
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user