diff --git a/packages/design-system/src/components/N8nAlert/Alert.stories.ts b/packages/design-system/src/components/N8nAlert/Alert.stories.ts new file mode 100644 index 0000000000..8a4eb35da4 --- /dev/null +++ b/packages/design-system/src/components/N8nAlert/Alert.stories.ts @@ -0,0 +1,65 @@ +import type { StoryFn } from '@storybook/vue'; +import N8nAlert from './Alert.vue'; +import N8nIcon from '../N8nIcon'; + +export default { + title: 'Atoms/Alert', + component: N8nAlert, + argTypes: { + type: { + type: 'select', + options: ['success', 'info', 'warning', 'error'], + }, + effect: { + type: 'select', + options: ['light', 'dark'], + }, + }, +}; + +const Template: StoryFn = (args, { argTypes }) => ({ + props: Object.keys(argTypes), + components: { + N8nAlert, + }, + template: + '
', +}); + +export const ContentAsProps = Template.bind({}); +ContentAsProps.args = { + type: 'info', + effect: 'light', + title: 'Alert title', + description: 'Alert description', + center: false, + showIcon: true, + background: true, +}; + +const TemplateForSlots: StoryFn = (args, { argTypes }) => ({ + props: Object.keys(argTypes), + components: { + N8nAlert, + N8nIcon, + }, + template: `
+ + + + + + +
`, +}); + +export const ContentInSlots = TemplateForSlots.bind({}); +ContentInSlots.args = { + type: 'info', + effect: 'light', + center: false, + background: true, + showIcon: false, +}; diff --git a/packages/design-system/src/components/N8nAlert/Alert.vue b/packages/design-system/src/components/N8nAlert/Alert.vue new file mode 100644 index 0000000000..a216f827b4 --- /dev/null +++ b/packages/design-system/src/components/N8nAlert/Alert.vue @@ -0,0 +1,242 @@ + + + + + diff --git a/packages/design-system/src/components/N8nAlert/__tests__/Alert.spec.ts b/packages/design-system/src/components/N8nAlert/__tests__/Alert.spec.ts new file mode 100644 index 0000000000..ea97015d88 --- /dev/null +++ b/packages/design-system/src/components/N8nAlert/__tests__/Alert.spec.ts @@ -0,0 +1,39 @@ +import { render, screen } from '@testing-library/vue'; +import N8nAlert from '../Alert.vue'; +import N8nIcon from '../../N8nIcon'; + +describe('components', () => { + describe('N8nAlert', () => { + it('should render with props', () => { + render(N8nAlert, { + props: { title: 'Title', description: 'Message' }, + }); + expect(screen.getByRole('alert')).toBeVisible(); + expect(screen.getByText('Title')).toBeVisible(); + expect(screen.getByText('Message')).toBeVisible(); + }); + + it('should render slots instead of props', () => { + const { container } = render( + N8nAlert, + { + props: { showIcon: false }, + slots: { + title: 'Title', + default: 'Message', + aside: '', + icon: '', + }, + }, + (localVue) => { + localVue.component('n8n-icon', N8nIcon); + }, + ); + expect(screen.getByRole('alert')).toBeVisible(); + expect(screen.getByText('Title')).toBeVisible(); + expect(screen.getByText('Message')).toBeVisible(); + expect(screen.getByRole('button')).toBeVisible(); + expect(container.querySelector('.n8n-icon')).toBeInTheDocument(); + }); + }); +}); diff --git a/packages/design-system/src/components/N8nAlert/index.ts b/packages/design-system/src/components/N8nAlert/index.ts new file mode 100644 index 0000000000..ea379c23a4 --- /dev/null +++ b/packages/design-system/src/components/N8nAlert/index.ts @@ -0,0 +1 @@ +export { default } from './Alert.vue'; diff --git a/packages/design-system/src/plugins/n8nComponents.ts b/packages/design-system/src/plugins/n8nComponents.ts index af315636bb..d56d4651cd 100644 --- a/packages/design-system/src/plugins/n8nComponents.ts +++ b/packages/design-system/src/plugins/n8nComponents.ts @@ -2,6 +2,7 @@ import Vue from 'vue'; import N8nActionBox from '../components/N8nActionBox'; import N8nActionDropdown from '../components/N8nActionDropdown'; import N8nActionToggle from '../components/N8nActionToggle'; +import N8nAlert from '../components/N8nAlert'; import N8nAvatar from '../components/N8nAvatar'; import N8nBadge from '../components/N8nBadge'; import N8nBlockUi from '../components/N8nBlockUi'; @@ -50,6 +51,7 @@ export default { app.component('n8n-action-box', N8nActionBox); app.component('n8n-action-dropdown', N8nActionDropdown); app.component('n8n-action-toggle', N8nActionToggle); + app.component('n8n-alert', N8nAlert); app.component('n8n-avatar', N8nAvatar); app.component('n8n-badge', N8nBadge); app.component('n8n-block-ui', N8nBlockUi);