move notification default layout to src/core
This commit is contained in:
@@ -1 +0,0 @@
|
||||
export * from './notification-layout-default.element';
|
||||
@@ -1,29 +0,0 @@
|
||||
import { html, LitElement } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import type { UmbNotificationHandler } from '../..';
|
||||
|
||||
export interface UmbNotificationDefaultData {
|
||||
message: string;
|
||||
headline?: string;
|
||||
}
|
||||
|
||||
@customElement('umb-notification-layout-default')
|
||||
export class UmbNotificationLayoutDefaultElement extends LitElement {
|
||||
static styles = [UUITextStyles];
|
||||
|
||||
@property({ attribute: false })
|
||||
notificationHandler!: UmbNotificationHandler;
|
||||
|
||||
@property({ type: Object })
|
||||
data!: UmbNotificationDefaultData;
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-toast-notification-layout id="layout" headline="${ifDefined(this.data.headline)}" class="uui-text">
|
||||
<div id="message">${this.data.message}</div>
|
||||
</uui-toast-notification-layout>
|
||||
`;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { Meta, Story } from '@storybook/web-components';
|
||||
import { html } from 'lit';
|
||||
import { UmbNotificationLayoutDefaultElement, UmbNotificationDefaultData } from '.';
|
||||
|
||||
export default {
|
||||
title: 'API/Notifications/Layouts/Default',
|
||||
component: 'umb-notification-layout-default',
|
||||
id: 'notification-layout-default',
|
||||
} as Meta;
|
||||
|
||||
const data: UmbNotificationDefaultData = {
|
||||
headline: 'Headline',
|
||||
message: 'This is a default notification',
|
||||
};
|
||||
|
||||
const Template: Story<UmbNotificationLayoutDefaultElement> = () => html`
|
||||
<uui-toast-notification .open=${true}>
|
||||
<umb-notification-layout-default .data=${data}></umb-notification-layout-default>
|
||||
</uui-toast-notification>
|
||||
`;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
@@ -1,56 +0,0 @@
|
||||
import { fixture, expect, html } from '@open-wc/testing';
|
||||
import { UUIToastNotificationLayoutElement } from '@umbraco-ui/uui';
|
||||
import { UmbNotificationHandler } from '../..';
|
||||
import type { UmbNotificationLayoutDefaultElement, UmbNotificationDefaultData } from '.';
|
||||
import '.';
|
||||
|
||||
describe('UmbNotificationLayoutDefault', () => {
|
||||
let element: UmbNotificationLayoutDefaultElement;
|
||||
|
||||
const data: UmbNotificationDefaultData = {
|
||||
headline: 'Notification Headline',
|
||||
message: 'Notification message',
|
||||
};
|
||||
|
||||
const options = { elementName: 'umb-notification-layout-default', data };
|
||||
|
||||
let notificationHandler: UmbNotificationHandler;
|
||||
|
||||
beforeEach(async () => {
|
||||
notificationHandler = new UmbNotificationHandler(options);
|
||||
element = await fixture(
|
||||
html`<umb-notification-layout-default
|
||||
.notificationHandler=${notificationHandler}
|
||||
.data=${options.data}></umb-notification-layout-default>`
|
||||
);
|
||||
});
|
||||
|
||||
describe('Public API', () => {
|
||||
describe('properties', () => {
|
||||
it('has a notificationHandler property', () => {
|
||||
expect(element).to.have.property('notificationHandler');
|
||||
});
|
||||
|
||||
it('has a data property', () => {
|
||||
expect(element).to.have.property('data');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Data options', () => {
|
||||
describe('Headline', () => {
|
||||
it('sets headline on uui notification layout', () => {
|
||||
const uuiNotificationLayout: UUIToastNotificationLayoutElement | null =
|
||||
element.renderRoot.querySelector('#layout');
|
||||
expect(uuiNotificationLayout?.getAttribute('headline')).to.equal('Notification Headline');
|
||||
});
|
||||
});
|
||||
|
||||
describe('message', () => {
|
||||
it('renders the message', () => {
|
||||
const messageElement: HTMLElement | null = element.renderRoot.querySelector('#message');
|
||||
expect(messageElement?.innerText).to.equal('Notification message');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -3,14 +3,13 @@ import { validate as uuidValidate } from 'uuid';
|
||||
|
||||
import { UmbNotificationHandler } from './notification-handler';
|
||||
|
||||
import type { UmbNotificationDefaultData } from './layouts/default';
|
||||
import type { UmbNotificationOptions } from './notification.context';
|
||||
|
||||
describe('UmbNotificationHandler', () => {
|
||||
let notificationHandler: UmbNotificationHandler;
|
||||
|
||||
beforeEach(async () => {
|
||||
const options: UmbNotificationOptions<UmbNotificationDefaultData> = {};
|
||||
const options: UmbNotificationOptions = {};
|
||||
notificationHandler = new UmbNotificationHandler(options);
|
||||
});
|
||||
|
||||
@@ -72,7 +71,7 @@ describe('UmbNotificationHandler', () => {
|
||||
let layoutElement: any;
|
||||
|
||||
beforeEach(async () => {
|
||||
const options: UmbNotificationOptions<UmbNotificationDefaultData> = {
|
||||
const options: UmbNotificationOptions = {
|
||||
color: 'positive',
|
||||
data: {
|
||||
message: 'Notification default layout message',
|
||||
@@ -100,7 +99,7 @@ describe('UmbNotificationHandler', () => {
|
||||
let layoutElement: any;
|
||||
|
||||
beforeEach(async () => {
|
||||
const options: UmbNotificationOptions<UmbNotificationDefaultData> = {
|
||||
const options: UmbNotificationOptions = {
|
||||
elementName: 'umb-notification-test-element',
|
||||
color: 'positive',
|
||||
data: {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { UUIToastNotificationElement } from '@umbraco-ui/uui';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import type { UmbNotificationOptions, UmbNotificationColor, UmbNotificationDefaultData } from '.';
|
||||
|
||||
import './layouts/default';
|
||||
import type { UmbNotificationOptions, UmbNotificationColor, UmbNotificationDefaultData } from './notification.context';
|
||||
|
||||
/**
|
||||
* @export
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
import { Meta } from '@storybook/blocks';
|
||||
|
||||
<Meta title="API/Notifications/Intro" />
|
||||
|
||||
# Notifications
|
||||
|
||||
Notifications appear in the bottom right corner of the Backoffice. There are two types of notifications: "Peek" and "Stay".
|
||||
|
||||
**Peek notifications**
|
||||
Goes away automatically and should be used as feedback on user actions.
|
||||
|
||||
**Stay notifications**
|
||||
Stays on the screen until dismissed by the user or custom code. Stay notification should be used when you need user feedback or want to control when the notification disappears.
|
||||
|
||||
## Basic usage
|
||||
|
||||
### Consume UmbNotificationContext from an element
|
||||
|
||||
The UmbNotification context can be used to open notifications.
|
||||
|
||||
```ts
|
||||
import { html, LitElement } from 'lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import type { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_ALIAS } from '@umbraco-cms/notification';
|
||||
|
||||
class MyElement extends UmbLitElement {
|
||||
private _notificationContext?: UmbNotificationContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_NOTIFICATION_CONTEXT_ALIAS, (instance) => {
|
||||
this._notificationContext = notificationContext;
|
||||
// notificationContext is now ready to be used
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Open a notification
|
||||
|
||||
A notification is opened by calling one of the helper methods on the UmbNotificationContext. The methods will return an instance of UmbNotificationHandler.
|
||||
|
||||
```ts
|
||||
import { html, LitElement } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import type {
|
||||
UmbNotificationContext,
|
||||
UmbNotificationDefaultData,
|
||||
UMB_NOTIFICATION_CONTEXT_ALIAS,
|
||||
} from '@umbraco-cms/notification';
|
||||
|
||||
class MyElement extends UmbLitElement {
|
||||
private _notificationContext?: UmbNotificationContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_NOTIFICATION_CONTEXT_ALIAS, (notificationContext) => {
|
||||
this._notificationContext = notificationContext;
|
||||
// notificationContext is now ready to be used
|
||||
});
|
||||
}
|
||||
|
||||
private _handleClick() {
|
||||
const data: UmbNotificationDefaultData = { headline: 'Look at this', message: 'Something good happened' };
|
||||
const notificationHandler = this._notificationContext?.peek('positive', { data });
|
||||
|
||||
notificationHandler.onClose().then(() => {
|
||||
// if you need any logic when the notification is closed you can run it here
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<button @click="${this._handleClick}">Open Notification</button>`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced usage: creating custom layouts
|
||||
|
||||
The default layout will cover most cases, but there might be situations where we want a more complex layout. You can create a new Custom Element to use as the layout.
|
||||
|
||||
### Custom layout element
|
||||
|
||||
```ts
|
||||
import { html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import type { UmbNotificationHandler } from '@umbraco-cms/notification';
|
||||
|
||||
export interface UmbNotificationCustomData {
|
||||
headline: string;
|
||||
user: {
|
||||
name: string;
|
||||
};
|
||||
}
|
||||
|
||||
export class UmbNotificationLayoutCustom extends LitElement {
|
||||
static styles = [UUITextStyles];
|
||||
|
||||
@property({ attribute: false })
|
||||
public notificationHandler: UmbNotificationHandler;
|
||||
|
||||
@property({ type: Object })
|
||||
public data: UmbNotificationCustomData;
|
||||
|
||||
private _handleConfirm() {
|
||||
this.notificationHandler.close(true);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-toast-notification-layout headline="${this.data.headline}" class="uui-text">
|
||||
${this.data.user.name}
|
||||
<uui-button slot="actions" @click="${this._handleConfirm}" label="Confirm">Confirm</uui-button>
|
||||
</uui-toast-notification-layout>
|
||||
`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Open notification with custom layout
|
||||
|
||||
```ts
|
||||
import { html, LitElement } from 'lit';
|
||||
import { UmbContextInjectMixin } from '@umbraco-cms/context-api';
|
||||
import type {
|
||||
UmbNotificationContext,
|
||||
UmbNotificationOptions,
|
||||
UMB_NOTIFICATION_CONTEXT_ALIAS,
|
||||
} from '@umbraco-cms/notification';
|
||||
import type { UmbNotificationCustomData } from './custom-notification-layout';
|
||||
|
||||
class MyElement extends LitElement {
|
||||
private _notificationContext?: UmbNotificationContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_NOTIFICATION_CONTEXT_ALIAS, (instance) => {
|
||||
this._notificationContext = instance;
|
||||
// notificationContext is now ready to be used
|
||||
});
|
||||
}
|
||||
|
||||
private _handleClick() {
|
||||
const options: UmbNotificationOptions<UmbNotificationCustomData> = {
|
||||
elementName: 'umb-notification-layout-custom',
|
||||
data: {
|
||||
headline: 'Attention',
|
||||
user: { name: 'Peter Parker' },
|
||||
},
|
||||
};
|
||||
|
||||
const notificationHandler = this._notificationContext?.stay('default', options);
|
||||
|
||||
notificationHandler.onClose().then((result) => {
|
||||
if (result) {
|
||||
console.log('He agreed!');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<button @click="${this._handleClick}">Open Notification</button>`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
- Keep messages in notifications short and friendly.
|
||||
- Only use headlines when you need extra attention to the notification
|
||||
- If a custom notification layout is only used in one module keep the files layout files local to that module.
|
||||
- If a custom notification will be used across the project. Create it as a layout in the notification folder and add a helper method to the UmbNotificationContext.
|
||||
@@ -1,38 +0,0 @@
|
||||
import '../layouts/default';
|
||||
|
||||
import { Meta, Story } from '@storybook/web-components';
|
||||
import { html } from 'lit';
|
||||
|
||||
import { UmbNotificationContext } from '..';
|
||||
|
||||
export default {
|
||||
title: 'API/Notifications/Overview',
|
||||
component: 'ucp-notification-layout-default',
|
||||
decorators: [
|
||||
(story) =>
|
||||
html`<umb-context-provider key="UmbNotificationContext" .value=${new UmbNotificationContext()}>
|
||||
${story()}
|
||||
</umb-context-provider>`,
|
||||
],
|
||||
} as Meta;
|
||||
|
||||
const Template: Story = () => html`<story-notification-default-example></story-notification-default-example>`;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.parameters = {
|
||||
docs: {
|
||||
source: {
|
||||
language: 'js',
|
||||
code: `
|
||||
const options: UmbNotificationOptions<UmbNotificationDefaultData> = {
|
||||
data: {
|
||||
headline: 'Headline',
|
||||
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
|
||||
}
|
||||
};
|
||||
|
||||
this._notificationContext?.peek('positive', options);
|
||||
`,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,56 +0,0 @@
|
||||
import { html } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import { UmbNotificationDefaultData } from '../layouts/default';
|
||||
import {
|
||||
UmbNotificationColor,
|
||||
UmbNotificationOptions,
|
||||
UmbNotificationContext,
|
||||
UMB_NOTIFICATION_CONTEXT_TOKEN,
|
||||
} from '..';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@customElement('story-notification-default-example')
|
||||
export class StoryNotificationDefaultExampleElement extends UmbLitElement {
|
||||
private _notificationContext?: UmbNotificationContext;
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
this.consumeContext(UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
|
||||
this._notificationContext = instance;
|
||||
});
|
||||
}
|
||||
|
||||
private _handleNotification = (color: UmbNotificationColor) => {
|
||||
const options: UmbNotificationOptions<UmbNotificationDefaultData> = {
|
||||
data: {
|
||||
headline: 'Headline',
|
||||
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
|
||||
},
|
||||
};
|
||||
this._notificationContext?.peek(color, options);
|
||||
};
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-button @click="${() => this._handleNotification('default')}" label="Default"></uui-button>
|
||||
<uui-button
|
||||
@click="${() => this._handleNotification('positive')}"
|
||||
label="Positive"
|
||||
look="primary"
|
||||
color="positive"></uui-button>
|
||||
<uui-button
|
||||
@click="${() => this._handleNotification('warning')}"
|
||||
label="Warning"
|
||||
look="primary"
|
||||
color="warning"></uui-button>
|
||||
<uui-button
|
||||
@click="${() => this._handleNotification('danger')}"
|
||||
label="Danger"
|
||||
look="primary"
|
||||
color="danger"></uui-button>
|
||||
|
||||
<umb-backoffice-notification-container></umb-backoffice-notification-container>
|
||||
`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user