Merge branch 'button' into 'main'
Button See merge request cellule-financiere-pmo/design-system/visua-vue!1
This commit is contained in:
commit
772bf1418f
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -30,3 +30,4 @@ coverage
|
|||
*.tsbuildinfo
|
||||
|
||||
.npmrc
|
||||
template
|
||||
|
|
|
@ -10,6 +10,11 @@ cache:
|
|||
- node_modules/
|
||||
|
||||
before_script:
|
||||
- echo "@cellule-financiere-pmo:registry=https://gitlab.com/api/v4/projects/71595796/packages/npm/" > .npmrc
|
||||
- echo "//gitlab.com/api/v4/projects/71595796/packages/npm/:username=${NPM_DEPLOY_USER}" >> .npmrc
|
||||
- echo "//gitlab.com/api/v4/projects/71595796/packages/npm/:_password=$(echo -n ${NPM_DEPLOY_TOKEN} | base64)" >> .npmrc
|
||||
- echo "//gitlab.com/api/v4/projects/71595796/packages/npm/:email=ci@example.com" >> .npmrc
|
||||
- echo "//gitlab.com/api/v4/projects/71595796/packages/npm/:always-auth=true" >> .npmrc
|
||||
- npm ci
|
||||
|
||||
unit-tests:
|
||||
|
@ -21,14 +26,11 @@ unit-tests:
|
|||
- coverage/
|
||||
expire_in: 1 month
|
||||
only:
|
||||
- branches
|
||||
- merge_requests
|
||||
|
||||
publish-npm:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "@cellule-financiere-pmo:registry=https://${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/" > .npmrc
|
||||
- echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}" >> .npmrc
|
||||
- npm publish
|
||||
only:
|
||||
- tags
|
1101
package-lock.json
generated
1101
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,8 @@
|
|||
"test:unit": "vitest run --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cellule-financiere-pmo/visua": "^1.1.0",
|
||||
"@cellule-financiere-pmo/visua": "1.1.3",
|
||||
"jsdom": "^26.1.0",
|
||||
"primevue": "^4.3.6",
|
||||
"vite-plugin-inspect": "^11.3.0",
|
||||
"vue": "^3.5.17"
|
||||
|
@ -22,6 +23,7 @@
|
|||
"@tsconfig/node22": "^22.0.2",
|
||||
"@types/node": "^22.15.32",
|
||||
"@vitejs/plugin-vue": "^6.0.0",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"@vue/eslint-config-typescript": "^14.5.1",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
|
@ -32,6 +34,7 @@
|
|||
"typescript": "~5.8.0",
|
||||
"vite": "^7.0.0",
|
||||
"vite-plugin-vue-devtools": "^7.7.7",
|
||||
"vitest": "^3.2.4",
|
||||
"vue-tsc": "^2.2.10"
|
||||
},
|
||||
"description": "**Current version: v0.0.0**",
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import VButtonView from '../template/VButtonView.vue'
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<VButtonView/>
|
||||
</template>
|
|
@ -1,6 +1,7 @@
|
|||
/* Adding styles */
|
||||
@import '../../../node_modules/@cellule-financiere-pmo/visua/output/variables.css';
|
||||
@import './global.css';
|
||||
@import '@visua/variables.css';
|
||||
@import './style/global.css';
|
||||
@import './style/primevue-configuration.css';
|
||||
|
||||
/* Basic setup */
|
||||
html {
|
1
src/assets/main.css
Normal file
1
src/assets/main.css
Normal file
|
@ -0,0 +1 @@
|
|||
@import './base.css';
|
1
src/assets/style/primevue-configuration.css
Normal file
1
src/assets/style/primevue-configuration.css
Normal file
|
@ -0,0 +1 @@
|
|||
@import './primevue-style/button.css';
|
67
src/assets/style/primevue-style/button.css
Normal file
67
src/assets/style/primevue-style/button.css
Normal file
|
@ -0,0 +1,67 @@
|
|||
:root{
|
||||
/* global style */
|
||||
--p-button-border-radius: 0px;
|
||||
--p-button-gap: 0.5rem;
|
||||
--p-button-label-font-weight: var(--text-body-MD-standard-text-Regular-weight);
|
||||
/* size: normal */
|
||||
--p-button-padding-x: 1rem;
|
||||
--p-button-padding-y: 0.5rem;
|
||||
--p-button-icon-only-width: 2.5rem;
|
||||
/* size: small */
|
||||
--p-button-sm-padding-x: 0.75rem;
|
||||
--p-button-sm-padding-y: 0.25rem;
|
||||
--p-button-sm-font-size: var(--text-body-SM-detail-text-Regular-size);
|
||||
--p-button-sm-icon-only-width: 2rem;
|
||||
/* size: large */
|
||||
--p-button-lg-padding-x: 1.5rem;
|
||||
--p-button-lg-padding-y: 0.625rem;
|
||||
--p-button-lg-font-size: var(--text-body-LG-article-text-Medium-size);
|
||||
--p-button-lg-icon-only-width: 3rem;
|
||||
/* variant: primary or default */
|
||||
--p-button-primary-background: var(--background-action-high-blue-france);
|
||||
--p-button-primary-hover-background: var(--background-action-high-blue-france-hover);
|
||||
--p-button-primary-active-background: var(--background-action-high-blue-france-active);
|
||||
--p-button-primary-border-color: transparent;
|
||||
--p-button-primary-hover-border-color: transparent;
|
||||
--p-button-primary-active-border-color: transparent;
|
||||
--p-button-primary-color: var(--text-inverted-blue-france);
|
||||
--p-button-primary-hover-color: var(--text-inverted-blue-france);
|
||||
--p-button-primary-active-color: var(--text-inverted-blue-france);
|
||||
/* variant: secondary */
|
||||
--p-button-secondary-background: var(--background-transparent);
|
||||
--p-button-secondary-hover-background: var(--background-transparent-hover);
|
||||
--p-button-secondary-active-background: var(--background-transparent-active);
|
||||
--p-button-secondary-border-color: var(--border-action-high-blue-france);
|
||||
--p-button-secondary-hover-border-color: var(--border-action-high-blue-france);
|
||||
--p-button-secondary-active-border-color: var(--border-action-high-blue-france);
|
||||
--p-button-outlined-secondary-hover-background: var(--background-transparent-hover);
|
||||
--p-button-outlined-secondary-active-background: var(--background-transparent-active);
|
||||
--p-button-outlined-secondary-border-color: var(--border-action-high-blue-france);
|
||||
--p-button-outlined-secondary-color: var(--text-action-high-blue-france);
|
||||
/* variant: tertiary */
|
||||
--p-button-outlined-primary-hover-background: var(--background-transparent-hover);
|
||||
--p-button-outlined-primary-active-background: var(--background-transparent-active);
|
||||
--p-button-outlined-primary-border-color: var(--border-default-grey);
|
||||
--p-button-outlined-primary-color: var(--text-action-high-blue-france);
|
||||
/* variant: no-outline */
|
||||
--p-button-text-primary-hover-background: var(--background-transparent-hover);
|
||||
--p-button-text-primary-active-background: var(--background-transparent-active);
|
||||
--p-button-text-primary-color: var(--text-action-high-blue-france);
|
||||
/* variant: danger */
|
||||
--p-button-danger-background: var(--primary-color-425-red-marianne-default);
|
||||
--p-button-danger-hover-background: var(--primary-color-425-red-marianne-hover);
|
||||
--p-button-danger-active-background: var(--primary-color-425-red-marianne-active);
|
||||
--p-button-danger-border-color: transparent;
|
||||
--p-button-danger-hover-border-color: transparent;
|
||||
--p-button-danger-active-border-color: transparent;
|
||||
--p-button-danger-color: var(--text-inverted-blue-france);
|
||||
--p-button-danger-hover-color: var(--text-inverted-blue-france);
|
||||
--p-button-danger-active-color: var(--text-inverted-blue-france);
|
||||
/* focus */
|
||||
--p-button-focus-ring-width: var(--focus-width);
|
||||
--p-button-focus-ring-style: var(--focus-style);
|
||||
--p-button-focus-ring-offset: var(--focus-offset);
|
||||
--p-button-primary-focus-ring-color: var(--focus-color);
|
||||
--p-button-secondary-focus-ring-color: var(--focus-color);
|
||||
--p-button-danger-focus-ring-color: var(--focus-color);
|
||||
}
|
74
src/components/button/IVButton.type.ts
Normal file
74
src/components/button/IVButton.type.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
import type { ButtonHTMLAttributes } from "vue"
|
||||
/**
|
||||
* Interface representing the properties of a single button component.
|
||||
*/
|
||||
export default interface IVButton {
|
||||
/** Whether the button is disabled */
|
||||
disabled?: boolean;
|
||||
|
||||
/** Text label displayed on the button */
|
||||
label?: string;
|
||||
|
||||
/** Applies the secondary button style */
|
||||
secondary?: boolean;
|
||||
|
||||
/** Applies the tertiary button style */
|
||||
tertiary?: boolean;
|
||||
|
||||
/** Displays the icon on the right side of the button */
|
||||
iconRight?: boolean;
|
||||
|
||||
/** Displays only the icon without any label */
|
||||
iconOnly?: boolean;
|
||||
|
||||
/** Removes the default outline style */
|
||||
noOutline?: boolean;
|
||||
|
||||
/** Applies a danger style to the button */
|
||||
danger?: boolean;
|
||||
|
||||
/** Size of the button */
|
||||
size?: 'sm' | 'small' | 'lg' | 'large' | 'md' | 'medium' | '' | undefined;
|
||||
|
||||
/** Name of the icon to display */
|
||||
icon?: string;
|
||||
|
||||
/** Click event handler */
|
||||
onClick?: ($event: MouseEvent) => void;
|
||||
|
||||
/** Tooltip or accessibility title for the button (required) */
|
||||
title: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface representing a group of buttons with layout and style options.
|
||||
*/
|
||||
export default interface IVButtonGroup {
|
||||
/**
|
||||
* Array of buttons to display in the group.
|
||||
* Each button can include standard HTML button attributes.
|
||||
*/
|
||||
buttons?: (IVButton & ButtonHTMLAttributes)[];
|
||||
|
||||
/** Reverses the order of the buttons */
|
||||
reverse?: boolean;
|
||||
|
||||
/** Makes all buttons in the group the same width */
|
||||
equisized?: boolean;
|
||||
|
||||
/** Aligns icons to the right for all buttons */
|
||||
iconRight?: boolean;
|
||||
|
||||
/** Alignment of the button group */
|
||||
align?: 'right' | 'center' | '' | undefined;
|
||||
|
||||
/**
|
||||
* Controls when the layout should switch to inline.
|
||||
* Can be based on screen size or always/never.
|
||||
*/
|
||||
inlineLayoutWhen?: 'always' | 'never' | 'sm' | 'small' | 'lg' | 'large' | 'md' | 'medium' | '' | true | undefined;
|
||||
|
||||
/** Size of all buttons in the group */
|
||||
size?: 'sm' | 'small' | 'lg' | 'large' | 'md' | 'medium' | '' | undefined;
|
||||
}
|
||||
|
120
src/components/button/VButton.vue
Normal file
120
src/components/button/VButton.vue
Normal file
|
@ -0,0 +1,120 @@
|
|||
<script setup lang="ts">
|
||||
import Button from 'primevue/button';
|
||||
import type IVButton from './IVButton.type';
|
||||
import { computed } from 'vue';
|
||||
import styles from '@visua/typography.module.css';
|
||||
|
||||
// Props configuration with default values
|
||||
const props = withDefaults(defineProps<IVButton>(), {
|
||||
disabled: false,
|
||||
label: undefined,
|
||||
secondary: false,
|
||||
tertiary: false,
|
||||
iconRight: false,
|
||||
iconOnly: false,
|
||||
noOutline: false,
|
||||
danger: false,
|
||||
size: 'md',
|
||||
icon: '',
|
||||
onClick: () => undefined,
|
||||
})
|
||||
|
||||
// Button size class computed
|
||||
const size = computed(() => {
|
||||
if (['sm', 'small'].includes(props.size)) return 'small';
|
||||
else if (['md', 'medium', '', undefined].includes(props.size)) return undefined;
|
||||
else if (['lg', 'large'].includes(props.size)) return 'large';
|
||||
else return undefined;
|
||||
})
|
||||
|
||||
// Icon position computed
|
||||
const iconPos = computed<string>(() => {
|
||||
return props.iconRight ? 'right': 'left'
|
||||
})
|
||||
|
||||
// Button variant computed
|
||||
const variant = computed(() => {
|
||||
if(props.noOutline) return 'text';
|
||||
else if (props.secondary || props.tertiary) return 'outlined';
|
||||
else return undefined;
|
||||
})
|
||||
|
||||
// Button severity computed
|
||||
const severity = computed(() => {
|
||||
if(props.secondary) return 'secondary';
|
||||
else if(props.danger) return 'danger';
|
||||
else return undefined
|
||||
});
|
||||
|
||||
// Button font computed
|
||||
const font = computed(() => {
|
||||
switch (size.value) {
|
||||
case 'large': return styles['text-body-LG-article-text-Regular'];
|
||||
case 'small': return styles['text-body-SM-detail-text-Regular'];
|
||||
default: return styles['text-body-MD-standard-text-Regular'];
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Button
|
||||
:label="props.iconOnly ? undefined : props.label"
|
||||
:variant="variant"
|
||||
:severity="severity"
|
||||
:icon="props.icon"
|
||||
:size="size"
|
||||
:class="['p-button', font]"
|
||||
v-bind="$attrs"
|
||||
:disabled="props.disabled"
|
||||
:aria-disabled="props.disabled"
|
||||
:icon-pos="iconPos"
|
||||
:onclick="props.onClick"
|
||||
:title="props.title"
|
||||
role="button"
|
||||
:aria-label="props.label"
|
||||
>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* disable state */
|
||||
.p-button:disabled{
|
||||
/* variant: primary or default */
|
||||
--p-button-primary-background: var(--background-disabled-grey);
|
||||
--p-button-primary-hover-background: var(--background-disabled-grey);
|
||||
--p-button-primary-active-background: var(--background-disabled-grey);
|
||||
--p-button-primary-color: var(--text-disabled-grey);
|
||||
--p-button-primary-hover-color: var(--text-disabled-grey);
|
||||
--p-button-primary-active-color: var(--text-disabled-grey);
|
||||
/* variant: danger */
|
||||
--p-button-danger-background: var(--background-disabled-grey);
|
||||
--p-button-danger-hover-background: var(--background-disabled-grey);
|
||||
--p-button-danger-active-background: var(--background-disabled-grey);
|
||||
--p-button-danger-color: var(--text-disabled-grey);
|
||||
--p-button-danger-hover-color: var(--text-disabled-grey);
|
||||
--p-button-danger-active-color: var(--text-disabled-grey);
|
||||
/* variant: secondary and tertiary */
|
||||
--p-button-secondary-background: var(--background-transparent);
|
||||
--p-button-secondary-hover-background: var(--background-transparent);
|
||||
--p-button-secondary-active-background: var(--background-transparent);
|
||||
--p-button-secondary-border-color: var(--border-disabled-grey);
|
||||
--p-button-secondary-hover-border-color: var(--border-disabled-grey);
|
||||
--p-button-secondary-active-border-color: var(--border-disabled-grey);
|
||||
|
||||
--p-button-outlined-primary-hover-background: var(--background-transparent);
|
||||
--p-button-outlined-primary-active-background: var(--background-transparent);
|
||||
--p-button-outlined-primary-border-color: var(--border-disabled-grey);
|
||||
--p-button-outlined-primary-color: var(--text-disabled-grey);
|
||||
--p-button-outlined-secondary-hover-background: var(--background-transparent);
|
||||
--p-button-outlined-secondary-active-background: var(--background-transparent);
|
||||
--p-button-outlined-secondary-border-color: var(--border-disabled-grey);
|
||||
--p-button-outlined-secondary-color: var(--text-disabled-grey);
|
||||
/* variant: no-outline */
|
||||
--p-button-text-primary-hover-background: var(--background-transparent);
|
||||
--p-button-text-primary-active-background: var(--background-transparent);
|
||||
--p-button-text-primary-color: var(--text-disabled-grey);
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,10 @@
|
|||
import './assets/main.css'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import primeVue from 'primevue/config'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(primeVue)
|
||||
|
||||
app.mount('#app')
|
||||
|
|
212
test/VButton.spec.ts
Normal file
212
test/VButton.spec.ts
Normal file
|
@ -0,0 +1,212 @@
|
|||
import { mount } from '@vue/test-utils'
|
||||
import VButton from '@/components/button/VButton.vue'
|
||||
import {test, expect, describe, vi} from 'vitest'
|
||||
|
||||
describe('VButton', () => {
|
||||
test('Displays button label', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
label: 'button label',
|
||||
title: 'button'
|
||||
}
|
||||
})
|
||||
// Check that the props label has gone through
|
||||
expect(wrapper.props('label')).toBe('button label')
|
||||
// Checks that the rendering contains the expected value
|
||||
expect(wrapper.text()).toContain('button label')
|
||||
});
|
||||
|
||||
test('Displays only icon button when iconOnly props is set', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
icon: 'ri-settings-4-line',
|
||||
iconOnly: true,
|
||||
label: 'label',
|
||||
title: 'button'
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
// check the rendering doesn't contain any button label
|
||||
expect(button.text()).toBe('')
|
||||
// Check the icon is present
|
||||
const icon = button.find('.p-button-icon')
|
||||
expect(icon.exists()).toBe(true)
|
||||
expect(icon.classes()).toContain('ri-settings-4-line')
|
||||
// check that the aria-label attribute is correctly defined
|
||||
expect(button.attributes('aria-label')).toBe('label')
|
||||
})
|
||||
|
||||
test('Displays label and button icon when both are set', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
icon: 'ri-settings-4-line'
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
// check the rendering contains button label value
|
||||
expect(button.text()).toBe('label')
|
||||
// Check the icon is present
|
||||
const icon = button.find('.p-button-icon')
|
||||
expect(icon.exists()).toBe(true)
|
||||
expect(icon.classes()).toContain('ri-settings-4-line')
|
||||
// check if the button icon is shown on left by default
|
||||
expect(icon.classes()).toContain('p-button-icon-left')
|
||||
// check that the aria-label attribute is correctly defined
|
||||
expect(button.attributes('aria-label')).toBe('label')
|
||||
})
|
||||
|
||||
test('Displays button icon on right when iconRight props is set', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
icon: 'ri-settings-4-line',
|
||||
iconRight: true
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
// Check if button icon is on right
|
||||
const iconRight = button.find('.p-button-icon-right')
|
||||
expect(iconRight.exists()).toBe(true)
|
||||
expect(iconRight.classes()).not.toContain('p-button-icon-left')
|
||||
})
|
||||
|
||||
test('Disabled button', async () => {
|
||||
const onClick = vi.fn()
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
disabled: true,
|
||||
onClick,
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
await button.trigger('click')
|
||||
// check disabled props is set
|
||||
expect(button.attributes('disabled')).toBeDefined()
|
||||
// check aria-disabled atribute is set
|
||||
expect(button.attributes('aria-disabled')).toBe('true')
|
||||
// check that the onClck function hasn't been called
|
||||
expect(onClick).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('small button', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
size: 'sm'
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
expect(button.classes()).toContain('p-button-sm')
|
||||
expect(button.classes()).not.toContain('p-button-lg')
|
||||
expect(button.classes().some(c => c.includes('text-body-SM'))).toBe(true)
|
||||
})
|
||||
|
||||
test('large button', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
size: 'lg'
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
expect(button.classes()).toContain('p-button-lg')
|
||||
expect(button.classes()).not.toContain('p-button-sm')
|
||||
expect(button.classes().some(c => c.includes('text-body-LG'))).toBe(true)
|
||||
})
|
||||
|
||||
test('medium button', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
expect(button.classes()).not.toContain('p-button-lg')
|
||||
expect(button.classes()).not.toContain('p-button-sm')
|
||||
expect(button.classes().some(c => c.includes('text-body-MD'))).toBe(true)
|
||||
})
|
||||
|
||||
test('primary button', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
expect(button.classes()).not.toContain('p-button-secondary')
|
||||
expect(button.classes()).not.toContain('p-button-outlined')
|
||||
expect(button.classes()).not.toContain('p-button-text')
|
||||
expect(button.classes()).not.toContain('p-button-danger')
|
||||
})
|
||||
|
||||
test('secondary button', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
secondary: true,
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
expect(button.classes()).toContain('p-button-secondary')
|
||||
expect(button.classes()).toContain('p-button-outlined')
|
||||
expect(button.classes()).not.toContain('p-button-text')
|
||||
expect(button.classes()).not.toContain('p-button-danger')
|
||||
expect(button.attributes('data-p-severity')).toBe('secondary')
|
||||
})
|
||||
|
||||
test('tertiary button', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
tertiary: true
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
expect(button.classes()).not.toContain('p-button-secondary')
|
||||
expect(button.classes()).toContain('p-button-outlined')
|
||||
expect(button.classes()).not.toContain('p-button-text')
|
||||
expect(button.classes()).not.toContain('p-button-danger')
|
||||
})
|
||||
|
||||
test('no outlined button', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
noOutline: true,
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
expect(button.classes()).not.toContain('p-button-secondary')
|
||||
expect(button.classes()).not.toContain('p-button-outlined')
|
||||
expect(button.classes()).toContain('p-button-text')
|
||||
expect(button.classes()).not.toContain('p-button-danger')
|
||||
})
|
||||
|
||||
test('danger variant button', () => {
|
||||
const wrapper = mount(VButton, {
|
||||
props: {
|
||||
title: 'button',
|
||||
label: 'label',
|
||||
danger: true,
|
||||
}
|
||||
})
|
||||
const button = wrapper.find('button')
|
||||
expect(button.classes()).not.toContain('p-button-secondary')
|
||||
expect(button.classes()).not.toContain('p-button-outlined')
|
||||
expect(button.classes()).not.toContain('p-button-text')
|
||||
expect(button.classes()).toContain('p-button-danger')
|
||||
expect(button.attributes('data-p-severity')).toBe('danger')
|
||||
})
|
||||
})
|
|
@ -1,12 +1,13 @@
|
|||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "test/VButton.spec.ts"],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
"@/*": ["./src/*"],
|
||||
"@visua/*": ["./node_modules/@cellule-financiere-pmo/visua/output/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,5 +7,8 @@
|
|||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
}
|
||||
]
|
||||
],
|
||||
"compilerOptions": {
|
||||
"types": ["vitest"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
import path from 'path'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
|
@ -12,7 +12,13 @@ export default defineConfig({
|
|||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
'@visua': path.resolve(__dirname, './node_modules/@cellule-financiere-pmo/visua/output')
|
||||
},
|
||||
},
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
include: ['test/**/*.spec.ts'],
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue
Block a user