diff --git a/examples/stencil-components/vanilla-cdn/index.html b/examples/stencil-components/vanilla-cdn/index.html index 8125fee2a5..4e205d1627 100644 --- a/examples/stencil-components/vanilla-cdn/index.html +++ b/examples/stencil-components/vanilla-cdn/index.html @@ -279,6 +279,15 @@

Multi-Select



+

Notification

+ Success notification +
+ Warning notification +
+ Error notification + +
+

Number Indicator

1 diff --git a/examples/wrapper-components/react-javascript/src/App.js b/examples/wrapper-components/react-javascript/src/App.js index aa2b0085d9..b7752e98ee 100644 --- a/examples/wrapper-components/react-javascript/src/App.js +++ b/examples/wrapper-components/react-javascript/src/App.js @@ -8,6 +8,7 @@ import SearchBar from './components/SearchBar/SearchBar.js'; import Accordion from './components/Accordion/Accordion.js'; import RadioButton from './components/RadioButton/RadioButton.js'; import Sidebar from './components/Sidebar/Sidebar.js'; +import Notification from './components/Notification/Notification.js' import NumberIndicator from './components/NumberIndicator/NumberIndicator.js' import Spinner from './components/Spinner/Spinner.js'; import Checkbox from './components/Checkbox/Checkbox.js'; @@ -103,6 +104,10 @@ function App() {
+

Notification

+ +
+

Number indicator


diff --git a/examples/wrapper-components/react-javascript/src/components/Notification/Notification.js b/examples/wrapper-components/react-javascript/src/components/Notification/Notification.js new file mode 100644 index 0000000000..836dc95651 --- /dev/null +++ b/examples/wrapper-components/react-javascript/src/components/Notification/Notification.js @@ -0,0 +1,15 @@ +import { IfxNotification } from '@infineon/infineon-design-system-react'; + +function Notification() { + return ( +
+ Success notification +
+ Warning notification +
+ Error notification +
+ ); +} + +export default Notification; \ No newline at end of file diff --git a/examples/wrapper-components/react-vite-js/src/App.jsx b/examples/wrapper-components/react-vite-js/src/App.jsx index 28d02d4b64..1460e07473 100644 --- a/examples/wrapper-components/react-vite-js/src/App.jsx +++ b/examples/wrapper-components/react-vite-js/src/App.jsx @@ -7,6 +7,7 @@ import SearchBar from './components/SearchBar/SearchBar'; import Accordion from './components/Accordion/Accordion'; import RadioButton from './components/RadioButton/RadioButton'; import Sidebar from './components/Sidebar/Sidebar' +import Notification from './components/Notification/Notification' import NumberIndicator from './components/NumberIndicator/NumberIndicator' import Spinner from './components/Spinner/Spinner' import Checkbox from './components/Checkbox/Checkbox'; @@ -103,6 +104,10 @@ function App() {
+

Notification

+ +
+

Number indicator


diff --git a/examples/wrapper-components/react-vite-js/src/components/Notification/Notification.jsx b/examples/wrapper-components/react-vite-js/src/components/Notification/Notification.jsx new file mode 100644 index 0000000000..836dc95651 --- /dev/null +++ b/examples/wrapper-components/react-vite-js/src/components/Notification/Notification.jsx @@ -0,0 +1,15 @@ +import { IfxNotification } from '@infineon/infineon-design-system-react'; + +function Notification() { + return ( +
+ Success notification +
+ Warning notification +
+ Error notification +
+ ); +} + +export default Notification; \ No newline at end of file diff --git a/examples/wrapper-components/vue-javascript/src/App.vue b/examples/wrapper-components/vue-javascript/src/App.vue index 6630ff55eb..da72565de6 100644 --- a/examples/wrapper-components/vue-javascript/src/App.vue +++ b/examples/wrapper-components/vue-javascript/src/App.vue @@ -18,6 +18,7 @@ + @@ -75,6 +76,7 @@ import Icon from './components/Icon.vue' import Slider from './components/Slider.vue' import Status from './components/Status.vue' import Stepper from './components/Stepper.vue' +import Notification from './components/Notification.vue' diff --git a/examples/wrapper-components/vue-javascript/src/components/Notification.vue b/examples/wrapper-components/vue-javascript/src/components/Notification.vue new file mode 100644 index 0000000000..b249fad783 --- /dev/null +++ b/examples/wrapper-components/vue-javascript/src/components/Notification.vue @@ -0,0 +1,10 @@ + diff --git a/packages/components-angular/projects/component-library/src/lib/stencil-generated/index.ts b/packages/components-angular/projects/component-library/src/lib/stencil-generated/index.ts index fc79c64693..6ec45a75a0 100644 --- a/packages/components-angular/projects/component-library/src/lib/stencil-generated/index.ts +++ b/packages/components-angular/projects/component-library/src/lib/stencil-generated/index.ts @@ -43,6 +43,7 @@ export const DIRECTIVES = [ d.IfxNavbar, d.IfxNavbarItem, d.IfxNavbarProfile, + d.IfxNotification, d.IfxNumberIndicator, d.IfxOverviewTable, d.IfxPagination, diff --git a/packages/components-react/src/components.ts b/packages/components-react/src/components.ts index 0fed9c025a..1819ff9137 100644 --- a/packages/components-react/src/components.ts +++ b/packages/components-react/src/components.ts @@ -49,6 +49,7 @@ import { IfxMultiselect as IfxMultiselectElement, defineCustomElement as defineI import { IfxNavbarItem as IfxNavbarItemElement, defineCustomElement as defineIfxNavbarItem } from "@infineon/infineon-design-system-stencil/dist/components/ifx-navbar-item.js"; import { IfxNavbarProfile as IfxNavbarProfileElement, defineCustomElement as defineIfxNavbarProfile } from "@infineon/infineon-design-system-stencil/dist/components/ifx-navbar-profile.js"; import { IfxNavbar as IfxNavbarElement, defineCustomElement as defineIfxNavbar } from "@infineon/infineon-design-system-stencil/dist/components/ifx-navbar.js"; +import { IfxNotification as IfxNotificationElement, defineCustomElement as defineIfxNotification } from "@infineon/infineon-design-system-stencil/dist/components/ifx-notification.js"; import { IfxNumberIndicator as IfxNumberIndicatorElement, defineCustomElement as defineIfxNumberIndicator } from "@infineon/infineon-design-system-stencil/dist/components/ifx-number-indicator.js"; import { IfxOverviewTable as IfxOverviewTableElement, defineCustomElement as defineIfxOverviewTable } from "@infineon/infineon-design-system-stencil/dist/components/ifx-overview-table.js"; import { IfxPagination as IfxPaginationElement, defineCustomElement as defineIfxPagination } from "@infineon/infineon-design-system-stencil/dist/components/ifx-pagination.js"; @@ -518,6 +519,16 @@ export const IfxNavbarProfile: StencilReactComponent; + +export const IfxNotification: StencilReactComponent = /*@__PURE__*/ createComponent({ + tagName: 'ifx-notification', + elementClass: IfxNotificationElement, + react: React, + events: {} as IfxNotificationEvents, + defineCustomElement: defineIfxNotification +}); + type IfxNumberIndicatorEvents = NonNullable; export const IfxNumberIndicator: StencilReactComponent = /*@__PURE__*/ createComponent({ diff --git a/packages/components/src/components/icon/readme.md b/packages/components/src/components/icon/readme.md index 9de434dd58..e3fe669f8f 100644 --- a/packages/components/src/components/icon/readme.md +++ b/packages/components/src/components/icon/readme.md @@ -39,6 +39,7 @@ - [ifx-multiselect](../select/multi-select) - [ifx-navbar](../navigation/navbar) - [ifx-navbar-item](../navigation/navbar) + - [ifx-notification](../notification) - [ifx-overview-table](../overview-table) - [ifx-search-bar](../search-bar) - [ifx-search-field](../search-field) @@ -69,6 +70,7 @@ graph TD; ifx-multiselect --> ifx-icon ifx-navbar --> ifx-icon ifx-navbar-item --> ifx-icon + ifx-notification --> ifx-icon ifx-overview-table --> ifx-icon ifx-search-bar --> ifx-icon ifx-search-field --> ifx-icon diff --git a/packages/components/src/components/link/readme.md b/packages/components/src/components/link/readme.md index 3ccc9fb308..dff74f59be 100644 --- a/packages/components/src/components/link/readme.md +++ b/packages/components/src/components/link/readme.md @@ -21,6 +21,7 @@ ### Used by - [ifx-footer](../footer) + - [ifx-notification](../notification) - [ifx-overview-table](../overview-table) - [ifx-step](../stepper/step) @@ -28,6 +29,7 @@ ```mermaid graph TD; ifx-footer --> ifx-link + ifx-notification --> ifx-link ifx-overview-table --> ifx-link ifx-step --> ifx-link style ifx-link fill:#f9f,stroke:#333,stroke-width:4px diff --git a/packages/components/src/components/notification/notification.e2e.ts b/packages/components/src/components/notification/notification.e2e.ts new file mode 100644 index 0000000000..4229aa755c --- /dev/null +++ b/packages/components/src/components/notification/notification.e2e.ts @@ -0,0 +1,68 @@ +import { newE2EPage } from "@stencil/core/testing"; + +describe('Notification', () => { + it('should render', async () => { + const page = await newE2EPage(); + await page.setContent('42'); + + const notification = await page.find('ifx-notification'); + expect(notification).toHaveClass('hydrated'); + }); + + it('should apply success class', async () => { + const page = await newE2EPage(); + await page.setContent('42'); + + const notification = await page.find('ifx-notification >>> .ifx-notification__wrapper'); + expect(notification).toHaveClass('ifx-notification__wrapper--success'); + }); + + it('should apply warning class', async () => { + const page = await newE2EPage(); + await page.setContent('42'); + + const notification = await page.find('ifx-notification >>> .ifx-notification__wrapper'); + expect(notification).toHaveClass('ifx-notification__wrapper--warning'); + }); + + it('should apply error class', async () => { + const page = await newE2EPage(); + await page.setContent('42'); + + const notification = await page.find('ifx-notification >>> .ifx-notification__wrapper'); + expect(notification).toHaveClass('ifx-notification__wrapper--error'); + }); + + it('should render icon', async () => { + const page = await newE2EPage(); + await page.setContent('42'); + + const icon = await page.find('ifx-notification >>> .ifx-notification__icon'); + expect(icon).not.toBeNull(); + }); + + it('should render link', async () => { + const page = await newE2EPage(); + await page.setContent('42'); + + const link = await page.find('ifx-notification >>> .ifx-notification__link'); + expect(await link.find('ifx-link')).not.toBeNull(); + expect(link).not.toBeNull(); + }); + + it('should render content', async () => { + const page = await newE2EPage(); + await page.setContent('42'); + + const content = await page.find('ifx-notification >>> .ifx-notification__content'); + expect(content).not.toBeNull(); + }); + + it('should render slot content', async () => { + const page = await newE2EPage(); + await page.setContent('42'); + + const content = await page.find('ifx-notification >>> .ifx-notification__content'); + expect(await content.find('slot')).not.toBeNull(); + }); +}); \ No newline at end of file diff --git a/packages/components/src/components/notification/notification.scss b/packages/components/src/components/notification/notification.scss new file mode 100644 index 0000000000..36dc4530d0 --- /dev/null +++ b/packages/components/src/components/notification/notification.scss @@ -0,0 +1,65 @@ +@use "~@infineon/design-system-tokens/dist/tokens"; +@use "../../global/font.scss"; + +.ifx-notification__wrapper { + display: flex; + flex-direction: row; + align-items: center; + + padding: tokens.$ifxSpace100 tokens.$ifxSpace200; + + background-color: tokens.$ifxColorBaseWhite; + font-family: var(--ifx-font-family); + color: tokens.$ifxColorBaseBlack; + + border: tokens.$ifxBorderWidth12 solid tokens.$ifxColorEngineering200; + + &.ifx-notification__wrapper--success { + border-left: tokens.$ifxBorderWidth50 solid tokens.$ifxColorGreen500; + + & .ifx-notification__icon { + color: tokens.$ifxColorGreen500; + } + } + + &.ifx-notification__wrapper--warning { + border-left: tokens.$ifxBorderWidth50 solid tokens.$ifxColorOrange500; + + & .ifx-notification__icon { + color: tokens.$ifxColorOrange500; + } + } + + &.ifx-notification__wrapper--error { + border-left: tokens.$ifxBorderWidth50 solid tokens.$ifxColorRed500; + + & .ifx-notification__icon { + color: tokens.$ifxColorRed500; + } + } + + & .ifx-notification__icon { + margin-right: tokens.$ifxSpace100; + display: flex; + } + + & .ifx-notification__body { + display: flex; + flex-direction: row; + flex-grow: 1; + + & .ifx-notification__slot { + flex-grow: 1; + } + } + + @media (max-width: tokens.$ifxBreakpointXs) { + & .ifx-notification__icon { + align-self: flex-start; + } + + & .ifx-notification__body { + flex-direction: column; + } + } +} \ No newline at end of file diff --git a/packages/components/src/components/notification/notification.stories.ts b/packages/components/src/components/notification/notification.stories.ts new file mode 100644 index 0000000000..db082c259d --- /dev/null +++ b/packages/components/src/components/notification/notification.stories.ts @@ -0,0 +1,48 @@ +export default { + title: 'Components/Notification', + tags: ['autodocs'], + + args: { + content: "Sample Notification", + variant: 'success', + icon: 'c-check-16', + linkText: 'Link', + linkHref: 'https://www.example.com', + linkTarget: '_blank', + }, + argTypes: { + content: { + description: 'Text inside the notification is passed as slot.', + }, + variant: { + description: 'Variant of the notification.', + options: ['success', 'warning', 'error'], + control: { type: 'radio' }, + }, + icon: { + description: 'The icon to be displayed in the notification.', + }, + linkText: { + description: 'Text for the link.', + }, + linkHref: { + description: 'URL for the link.', + }, + linkTarget:{ + options: ['_blank', '_self', '_parent'], + control: { type: 'radio' }, + }, + }, +}; + +const DefaultTemplate = args => ` + ${args.content} +`; + +export const Default = DefaultTemplate.bind({}); +Default.argTypes = {}; diff --git a/packages/components/src/components/notification/notification.tsx b/packages/components/src/components/notification/notification.tsx new file mode 100644 index 0000000000..a9a409bd19 --- /dev/null +++ b/packages/components/src/components/notification/notification.tsx @@ -0,0 +1,55 @@ +import { Component, h, Host, Prop } from '@stencil/core'; + +export type NotificationVariant = 'success' | 'warning' | 'error'; + +@Component({ + tag: 'ifx-notification', + styleUrl: 'notification.scss', + shadow: true +}) +export class Notification { + @Prop() icon: string; + @Prop() variant: NotificationVariant = 'success'; + @Prop() linkText: string; + @Prop() linkHref: string; + @Prop() linkTarget: string = '_blank'; + + + private getClassName(): string { + switch (this.variant) { + case 'success': + return 'ifx-notification__wrapper--success'; + case 'warning': + return 'ifx-notification__wrapper--warning'; + case 'error': + return 'ifx-notification__wrapper--error'; + default: + return 'ifx-notification__wrapper--success'; + } + } + + render() { + return ( + +
+
+ +
+
+
+ +
+ { this.linkText && this.linkHref && + + } +
+
+
+ ); + } +} \ No newline at end of file diff --git a/packages/components/src/components/notification/readme.md b/packages/components/src/components/notification/readme.md new file mode 100644 index 0000000000..aeac02ae2f --- /dev/null +++ b/packages/components/src/components/notification/readme.md @@ -0,0 +1,36 @@ +# ifx-notification + + + + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| ------------ | ------------- | ----------- | ----------------------------------- | ----------- | +| `icon` | `icon` | | `string` | `undefined` | +| `linkHref` | `link-href` | | `string` | `undefined` | +| `linkTarget` | `link-target` | | `string` | `'_blank'` | +| `linkText` | `link-text` | | `string` | `undefined` | +| `variant` | `variant` | | `"error" \| "success" \| "warning"` | `'success'` | + + +## Dependencies + +### Depends on + +- [ifx-icon](../icon) +- [ifx-link](../link) + +### Graph +```mermaid +graph TD; + ifx-notification --> ifx-icon + ifx-notification --> ifx-link + style ifx-notification fill:#f9f,stroke:#333,stroke-width:4px +``` + +---------------------------------------------- + +*Built with [StencilJS](https://stenciljs.com/)*