@genesislcap/foundation-notifications 14.400.0 → 14.401.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dts/container/index.d.ts +3 -0
- package/dist/dts/container/index.d.ts.map +1 -0
- package/dist/dts/container/notify-container-builder.d.ts +9 -0
- package/dist/dts/container/notify-container-builder.d.ts.map +1 -0
- package/dist/dts/container/notify-container.d.ts +41 -0
- package/dist/dts/container/notify-container.d.ts.map +1 -0
- package/dist/dts/container/notify-container.styles.d.ts +2 -0
- package/dist/dts/container/notify-container.styles.d.ts.map +1 -0
- package/dist/dts/container/notify-container.template.d.ts +3 -0
- package/dist/dts/container/notify-container.template.d.ts.map +1 -0
- package/dist/dts/index.d.ts +1 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/toast/toast-launcher.d.ts.map +1 -1
- package/dist/esm/container/index.js +2 -0
- package/dist/esm/container/notify-container-builder.js +29 -0
- package/dist/esm/container/notify-container.js +129 -0
- package/dist/esm/container/notify-container.styles.js +211 -0
- package/dist/esm/container/notify-container.template.js +33 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/toast/toast-launcher.js +39 -30
- package/dist/foundation-notifications.api.json +559 -0
- package/dist/foundation-notifications.d.ts +49 -0
- package/docs/api/foundation-notifications.configurenotifications.md +52 -0
- package/docs/api/foundation-notifications.md +29 -0
- package/docs/api/foundation-notifications.notifycontainer.allowcloseall.md +11 -0
- package/docs/api/foundation-notifications.notifycontainer.allowmanualcollapse.md +11 -0
- package/docs/api/foundation-notifications.notifycontainer.designsystemprefix.md +11 -0
- package/docs/api/foundation-notifications.notifycontainer.disconnectedcallback.md +15 -0
- package/docs/api/foundation-notifications.notifycontainer.md +208 -0
- package/docs/api/foundation-notifications.notifycontainer.position.md +11 -0
- package/docs/api/foundation-notifications.notifycontainer.showcount.md +11 -0
- package/docs/api/foundation-notifications.notifycontainer.slottednodes.md +11 -0
- package/docs/api/foundation-notifications.notifycontainer.stackcollapsed.md +11 -0
- package/docs/api/foundation-notifications.notifycontainer.stackthreshold.md +11 -0
- package/docs/api/foundation-notifications.notifycontainerconfig.allowcloseall.md +11 -0
- package/docs/api/foundation-notifications.notifycontainerconfig.allowmanualcollapse.md +11 -0
- package/docs/api/foundation-notifications.notifycontainerconfig.designsystemprefix.md +11 -0
- package/docs/api/foundation-notifications.notifycontainerconfig.md +139 -0
- package/docs/api/foundation-notifications.notifycontainerconfig.position.md +11 -0
- package/docs/api/foundation-notifications.notifycontainerconfig.showcount.md +11 -0
- package/docs/api/foundation-notifications.notifycontainerconfig.stackthreshold.md +11 -0
- package/docs/api-report.md.api.md +52 -0
- package/package.json +12 -11
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/container/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NotifyContainerConfig } from './notify-container';
|
|
2
|
+
/**
|
|
3
|
+
* Configures a `notify-container` component used to opt-into new behaviours for toast notifications such as stacking
|
|
4
|
+
* You can have a `notify-container` in each of the four corners of the screen.
|
|
5
|
+
* If you call this function for a `ToastPosition` and it does not yet exist then this function
|
|
6
|
+
* will create one. If it already exists then this will override its config
|
|
7
|
+
*/
|
|
8
|
+
export declare const configureNotifications: (config: Partial<NotifyContainerConfig>) => void;
|
|
9
|
+
//# sourceMappingURL=notify-container-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify-container-builder.d.ts","sourceRoot":"","sources":["../../../src/container/notify-container-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAI5E;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,OAAO,CAAC,qBAAqB,CAAC,KAAG,IAwB/E,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { GenesisElement } from '@genesislcap/web-core';
|
|
2
|
+
import { ToastPosition } from '../types';
|
|
3
|
+
export interface NotifyContainerConfig {
|
|
4
|
+
position: ToastPosition;
|
|
5
|
+
stackThreshold: number;
|
|
6
|
+
allowManualCollapse: boolean;
|
|
7
|
+
allowCloseAll: boolean;
|
|
8
|
+
designSystemPrefix: string;
|
|
9
|
+
showCount: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare class NotifyContainer extends GenesisElement implements NotifyContainerConfig {
|
|
12
|
+
position: ToastPosition;
|
|
13
|
+
stackThreshold: number;
|
|
14
|
+
allowManualCollapse: boolean;
|
|
15
|
+
allowCloseAll: boolean;
|
|
16
|
+
designSystemPrefix: string;
|
|
17
|
+
showCount: boolean;
|
|
18
|
+
stackCollapsed: boolean;
|
|
19
|
+
private manuallyExpanded;
|
|
20
|
+
private routeSubscriber;
|
|
21
|
+
/** @internal */
|
|
22
|
+
connectedCallback(): void;
|
|
23
|
+
disconnectedCallback(): void;
|
|
24
|
+
private checkRoute;
|
|
25
|
+
slottedNodes: Node[];
|
|
26
|
+
/** @internal */
|
|
27
|
+
slottedNodesChanged(): void;
|
|
28
|
+
/** @internal */
|
|
29
|
+
handleContainerClick(): void;
|
|
30
|
+
/** @internal */
|
|
31
|
+
handleToggleCollapse(): void;
|
|
32
|
+
/** @internal */
|
|
33
|
+
handleCloseAll(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Manages the absolute positioning of notifications to enable smooth stack-to-list animations.
|
|
36
|
+
* Uses a batch read/write pattern to avoid layout thrashing.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
private handlePosition;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=notify-container.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify-container.d.ts","sourceRoot":"","sources":["../../../src/container/notify-container.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,cAAc,EAA0B,MAAM,uBAAuB,CAAC;AAEpG,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,aAAa,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;CACpB;AAID,qBAKa,eAAgB,SAAQ,cAAe,YAAW,qBAAqB;IAC5E,QAAQ,EAAE,aAAa,CAAe;IACJ,cAAc,EAAE,MAAM,CAAqB;IACpB,mBAAmB,EAAE,OAAO,CACpF;IACkD,aAAa,EAAE,OAAO,CAAQ;IAC1C,kBAAkB,EAAE,MAAM,CAAW;IAC9B,SAAS,EAAE,OAAO,CAAQ;IAErB,cAAc,EAAE,OAAO,CAAS;IAEzF,OAAO,CAAC,gBAAgB,CAAkB;IAE1C,OAAO,CAAC,eAAe,CAErB;IAEF,gBAAgB;IAChB,iBAAiB,IAAI,IAAI;IAUzB,oBAAoB,IAAI,IAAI;IAK5B,OAAO,CAAC,UAAU;IAMN,YAAY,EAAE,IAAI,EAAE,CAAM;IACtC,gBAAgB;IAChB,mBAAmB;IAiBnB,gBAAgB;IAChB,oBAAoB;IAOpB,gBAAgB;IAChB,oBAAoB;IAKpB,gBAAgB;IAChB,cAAc;IAQd;;;;OAIG;IACH,OAAO,CAAC,cAAc;CAsBvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify-container.styles.d.ts","sourceRoot":"","sources":["../../../src/container/notify-container.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM,iDAiNlB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify-container.template.d.ts","sourceRoot":"","sources":["../../../src/container/notify-container.template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAoCrD,eAAO,MAAM,QAAQ,sEAUpB,CAAC"}
|
package/dist/dts/index.d.ts
CHANGED
package/dist/dts/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast-launcher.d.ts","sourceRoot":"","sources":["../../../src/toast/toast-launcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"toast-launcher.d.ts","sourceRoot":"","sources":["../../../src/toast/toast-launcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAiB,MAAM,UAAU,CAAC;AAiChE;;;;;;;KAOK;AACL,eAAO,MAAM,SAAS,GACpB,uBAAuB,qBAAqB,EAC5C,SAAS,MAAM,EACf,wBAAwB,WAAW,KAClC,IAgFF,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getCurrentDesignSystem } from '@genesislcap/foundation-utils';
|
|
2
|
+
import { NotifyContainer } from './notify-container';
|
|
3
|
+
NotifyContainer;
|
|
4
|
+
/**
|
|
5
|
+
* Configures a `notify-container` component used to opt-into new behaviours for toast notifications such as stacking
|
|
6
|
+
* You can have a `notify-container` in each of the four corners of the screen.
|
|
7
|
+
* If you call this function for a `ToastPosition` and it does not yet exist then this function
|
|
8
|
+
* will create one. If it already exists then this will override its config
|
|
9
|
+
*/
|
|
10
|
+
export const configureNotifications = (config) => {
|
|
11
|
+
// TODO: we can support this later
|
|
12
|
+
if (config.position === 'bottom-left' || config.position === 'bottom-right') {
|
|
13
|
+
throw new Error("NotifyContainer doesn't currently support bottom corner placements");
|
|
14
|
+
}
|
|
15
|
+
const { element: providerElement } = getCurrentDesignSystem(document.body, 'rapid');
|
|
16
|
+
if (!providerElement) {
|
|
17
|
+
// TODO: later we can make this more robust
|
|
18
|
+
throw new Error('Cannot find design system provider');
|
|
19
|
+
}
|
|
20
|
+
const mExistingContainer = Array.from(providerElement.querySelectorAll('notify-container')).find((elem) => { var _a; return elem.position === ((_a = config === null || config === void 0 ? void 0 : config.position) !== null && _a !== void 0 ? _a : 'top-right'); });
|
|
21
|
+
const container = (() => {
|
|
22
|
+
if (mExistingContainer)
|
|
23
|
+
return mExistingContainer;
|
|
24
|
+
const newContainer = document.createElement('notify-container');
|
|
25
|
+
providerElement.appendChild(newContainer);
|
|
26
|
+
return newContainer;
|
|
27
|
+
})();
|
|
28
|
+
Object.entries(config).forEach(([k, v]) => (container[k] = v));
|
|
29
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { RouteUtil } from '@genesislcap/foundation-utils';
|
|
3
|
+
import { attr, customElement, GenesisElement, observable, Observable } from '@genesislcap/web-core';
|
|
4
|
+
import { logger } from '../logger';
|
|
5
|
+
import { styles } from './notify-container.styles';
|
|
6
|
+
import { template } from './notify-container.template';
|
|
7
|
+
const DEFAULT_THRESHOLD = 5;
|
|
8
|
+
let NotifyContainer = class NotifyContainer extends GenesisElement {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.position = 'top-right';
|
|
12
|
+
this.stackThreshold = DEFAULT_THRESHOLD;
|
|
13
|
+
this.allowManualCollapse = true;
|
|
14
|
+
this.allowCloseAll = true;
|
|
15
|
+
this.designSystemPrefix = 'rapid';
|
|
16
|
+
this.showCount = true;
|
|
17
|
+
this.stackCollapsed = false;
|
|
18
|
+
this.manuallyExpanded = false;
|
|
19
|
+
this.routeSubscriber = {
|
|
20
|
+
handleChange: () => this.checkRoute(RouteUtil.shared.pathName),
|
|
21
|
+
};
|
|
22
|
+
this.slottedNodes = [];
|
|
23
|
+
}
|
|
24
|
+
/** @internal */
|
|
25
|
+
connectedCallback() {
|
|
26
|
+
super.connectedCallback();
|
|
27
|
+
if (this.position === 'bottom-left' || this.position === 'bottom-right') {
|
|
28
|
+
logger.error("NotifyContainer doesn't currently support bottom corner placements");
|
|
29
|
+
}
|
|
30
|
+
Observable.getNotifier(RouteUtil.shared).subscribe(this.routeSubscriber, 'pathName');
|
|
31
|
+
this.checkRoute(RouteUtil.shared.pathName);
|
|
32
|
+
}
|
|
33
|
+
disconnectedCallback() {
|
|
34
|
+
super.disconnectedCallback();
|
|
35
|
+
Observable.getNotifier(RouteUtil.shared).unsubscribe(this.routeSubscriber, 'pathName');
|
|
36
|
+
}
|
|
37
|
+
checkRoute(path) {
|
|
38
|
+
if (path.includes('/login') || path.includes('/logout')) {
|
|
39
|
+
this.handleCloseAll();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** @internal */
|
|
43
|
+
slottedNodesChanged() {
|
|
44
|
+
if (!this.manuallyExpanded &&
|
|
45
|
+
!this.stackCollapsed &&
|
|
46
|
+
this.slottedNodes.length > this.stackThreshold) {
|
|
47
|
+
this.stackCollapsed = true;
|
|
48
|
+
}
|
|
49
|
+
if (this.stackCollapsed && this.slottedNodes.length <= 1) {
|
|
50
|
+
this.stackCollapsed = false;
|
|
51
|
+
this.manuallyExpanded = false;
|
|
52
|
+
}
|
|
53
|
+
this.handlePosition();
|
|
54
|
+
}
|
|
55
|
+
/** @internal */
|
|
56
|
+
handleContainerClick() {
|
|
57
|
+
if (this.stackCollapsed) {
|
|
58
|
+
this.stackCollapsed = false;
|
|
59
|
+
this.manuallyExpanded = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** @internal */
|
|
63
|
+
handleToggleCollapse() {
|
|
64
|
+
this.stackCollapsed = !this.stackCollapsed;
|
|
65
|
+
this.manuallyExpanded = !this.stackCollapsed;
|
|
66
|
+
}
|
|
67
|
+
/** @internal */
|
|
68
|
+
handleCloseAll() {
|
|
69
|
+
while (this.firstChild) {
|
|
70
|
+
this.removeChild(this.firstChild);
|
|
71
|
+
}
|
|
72
|
+
this.stackCollapsed = false;
|
|
73
|
+
this.manuallyExpanded = false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Manages the absolute positioning of notifications to enable smooth stack-to-list animations.
|
|
77
|
+
* Uses a batch read/write pattern to avoid layout thrashing.
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
handlePosition() {
|
|
81
|
+
const toasts = this.slottedNodes.filter((node) => node instanceof HTMLElement);
|
|
82
|
+
if (!toasts.length) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
toasts.forEach((toast, index) => {
|
|
86
|
+
toast.style.position = 'absolute';
|
|
87
|
+
toast.style.transition = 'all 0.3s ease-in';
|
|
88
|
+
toast.style.right = '0px';
|
|
89
|
+
toast.style.zIndex = (toasts.length - index).toString();
|
|
90
|
+
});
|
|
91
|
+
const heights = toasts.map((toast) => toast.offsetHeight);
|
|
92
|
+
toasts.reduce((yOffset, toast, index) => {
|
|
93
|
+
toast.style.top = `${yOffset}px`;
|
|
94
|
+
return yOffset + heights[index];
|
|
95
|
+
}, 0);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
__decorate([
|
|
99
|
+
attr
|
|
100
|
+
], NotifyContainer.prototype, "position", void 0);
|
|
101
|
+
__decorate([
|
|
102
|
+
attr({ attribute: 'stack-threshold' })
|
|
103
|
+
], NotifyContainer.prototype, "stackThreshold", void 0);
|
|
104
|
+
__decorate([
|
|
105
|
+
attr({ attribute: 'allow-manual-collapse', mode: 'boolean' })
|
|
106
|
+
], NotifyContainer.prototype, "allowManualCollapse", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
attr({ attribute: 'allow-close-all', mode: 'boolean' })
|
|
109
|
+
], NotifyContainer.prototype, "allowCloseAll", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
attr({ attribute: 'design-system-prefix' })
|
|
112
|
+
], NotifyContainer.prototype, "designSystemPrefix", void 0);
|
|
113
|
+
__decorate([
|
|
114
|
+
attr({ attribute: 'show-count', mode: 'boolean' })
|
|
115
|
+
], NotifyContainer.prototype, "showCount", void 0);
|
|
116
|
+
__decorate([
|
|
117
|
+
attr({ attribute: 'stack-collapsed', mode: 'boolean' })
|
|
118
|
+
], NotifyContainer.prototype, "stackCollapsed", void 0);
|
|
119
|
+
__decorate([
|
|
120
|
+
observable
|
|
121
|
+
], NotifyContainer.prototype, "slottedNodes", void 0);
|
|
122
|
+
NotifyContainer = __decorate([
|
|
123
|
+
customElement({
|
|
124
|
+
name: 'notify-container',
|
|
125
|
+
template,
|
|
126
|
+
styles,
|
|
127
|
+
})
|
|
128
|
+
], NotifyContainer);
|
|
129
|
+
export { NotifyContainer };
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { css } from '@genesislcap/web-core';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
position: fixed;
|
|
5
|
+
z-index: 9999;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
gap: 4px;
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
pointer-events: none; /* Allow clicks to pass through empty space */
|
|
11
|
+
width: 415px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.toast-container {
|
|
15
|
+
padding: 0 8px 12px 12px;
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Expanded / List State: Allow scrolling if too many items */
|
|
20
|
+
|
|
21
|
+
:host(:not([stack-collapsed])) {
|
|
22
|
+
max-height: calc(100% - var(--nav-height));
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
pointer-events: auto; /* Enable pointer events for scrolling */
|
|
25
|
+
|
|
26
|
+
slot {
|
|
27
|
+
display: block;
|
|
28
|
+
height: calc(100vh - var(--nav-height) - 54px);
|
|
29
|
+
position: relative;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.toast-container {
|
|
33
|
+
flex: 1;
|
|
34
|
+
height: 100%;
|
|
35
|
+
overflow-y: auto;
|
|
36
|
+
overflow-x: hidden;
|
|
37
|
+
scrollbar-color: var(--neutral-layer-3) transparent;
|
|
38
|
+
|
|
39
|
+
&:hover {
|
|
40
|
+
scrollbar-color: var(--neutral-layer-4) transparent;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.header {
|
|
46
|
+
display: flex;
|
|
47
|
+
gap: 12px;
|
|
48
|
+
pointer-events: none;
|
|
49
|
+
margin: 5px 24px;
|
|
50
|
+
justify-content: space-between;
|
|
51
|
+
visibility: hidden;
|
|
52
|
+
align-items: center;
|
|
53
|
+
box-sizing: border-box;
|
|
54
|
+
|
|
55
|
+
.header-title {
|
|
56
|
+
text-shadow: 0 0 10px #000;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.notification-header-buttons {
|
|
60
|
+
display: flex;
|
|
61
|
+
gap: 4px;
|
|
62
|
+
|
|
63
|
+
rapid-icon {
|
|
64
|
+
color: var(--neutral-foreground-hint);
|
|
65
|
+
margin-left: 4px;
|
|
66
|
+
display: inline-flex;
|
|
67
|
+
font-size: 14px;
|
|
68
|
+
|
|
69
|
+
&.chevron-up.collapse {
|
|
70
|
+
transform: rotate(180deg);
|
|
71
|
+
transition: transform 0.3s ease;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
--base-height-multiplier: 8;
|
|
77
|
+
|
|
78
|
+
*[appearance='neutral'] {
|
|
79
|
+
font-size: 11px;
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
background: var(--neutral-fill-rest);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.header.visible {
|
|
86
|
+
visibility: visible;
|
|
87
|
+
pointer-events: auto; /* Enable clicks on header buttons */
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
:host([position$='left']) .header {
|
|
91
|
+
justify-content: space-between;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
:host([position^='bottom']) .header {
|
|
95
|
+
margin-bottom: 0;
|
|
96
|
+
margin-top: 4px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Ensure children (toasts) are clickable */
|
|
100
|
+
|
|
101
|
+
::slotted(*) {
|
|
102
|
+
pointer-events: auto;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
:host([position='top-right']) {
|
|
106
|
+
top: var(--nav-height, 0);
|
|
107
|
+
right: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
:host([position='top-left']) {
|
|
111
|
+
top: var(--nav-height, 0);
|
|
112
|
+
left: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
:host([position='bottom-right']) {
|
|
116
|
+
bottom: 0;
|
|
117
|
+
right: 0;
|
|
118
|
+
flex-direction: column-reverse;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
:host([position='bottom-left']) {
|
|
122
|
+
bottom: 0;
|
|
123
|
+
left: 0;
|
|
124
|
+
flex-direction: column-reverse;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* Stacked / Collapsed State */
|
|
128
|
+
|
|
129
|
+
:host([stack-collapsed]) {
|
|
130
|
+
height: min-content;
|
|
131
|
+
|
|
132
|
+
/* Host allows pointer events so they can reach the slot */
|
|
133
|
+
pointer-events: auto;
|
|
134
|
+
cursor: pointer;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Apply the grid layout to the slot itself so it acts as the container and click target */
|
|
138
|
+
|
|
139
|
+
:host([stack-collapsed]) slot {
|
|
140
|
+
display: grid;
|
|
141
|
+
grid-template-columns: auto;
|
|
142
|
+
grid-template-rows: auto;
|
|
143
|
+
align-items: end; /* Default to bottom-up stacking */
|
|
144
|
+
justify-items: center;
|
|
145
|
+
|
|
146
|
+
/* The slot catches the click */
|
|
147
|
+
pointer-events: auto;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Rotate when the collapse class is present */
|
|
151
|
+
|
|
152
|
+
:host([stack-collapsed][position^='top']) slot {
|
|
153
|
+
align-items: start;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
:host([stack-collapsed][position$='right']) slot {
|
|
157
|
+
justify-items: end;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
:host([stack-collapsed][position$='left']) slot {
|
|
161
|
+
justify-items: start;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
:host([stack-collapsed]) ::slotted(*) {
|
|
165
|
+
grid-area: 1 / 1;
|
|
166
|
+
transition:
|
|
167
|
+
transform 0.3s ease,
|
|
168
|
+
top 0.3s ease,
|
|
169
|
+
opacity 0.3s ease;
|
|
170
|
+
opacity: 0%;
|
|
171
|
+
pointer-events: none !important; /* Disable interaction with toasts in collapsed state */
|
|
172
|
+
transform: scale(0.9);
|
|
173
|
+
top: 0 !important;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Show and offset the top 3 items in the stack */
|
|
177
|
+
|
|
178
|
+
:host([stack-collapsed]) ::slotted(:nth-child(1)) {
|
|
179
|
+
opacity: 100%;
|
|
180
|
+
pointer-events: auto;
|
|
181
|
+
transform: translateY(0) scale(1);
|
|
182
|
+
z-index: 3;
|
|
183
|
+
position: relative !important;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
:host([stack-collapsed]) ::slotted(:nth-child(2)) {
|
|
187
|
+
opacity: 100%;
|
|
188
|
+
transform: translateY(var(--stack-offset-y, 8px)) scale(0.95);
|
|
189
|
+
z-index: 2;
|
|
190
|
+
position: relative !important;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
:host([stack-collapsed]) ::slotted(:nth-child(3)) {
|
|
194
|
+
opacity: 100%;
|
|
195
|
+
transform: translateY(var(--stack-offset-y-2, 16px)) scale(0.9);
|
|
196
|
+
z-index: 1;
|
|
197
|
+
position: relative !important;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* Adjust offset direction based on position */
|
|
201
|
+
|
|
202
|
+
:host([stack-collapsed][position^='top']) {
|
|
203
|
+
--stack-offset-y: 8px;
|
|
204
|
+
--stack-offset-y-2: 16px;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
:host([stack-collapsed][position^='bottom']) {
|
|
208
|
+
--stack-offset-y: -8px;
|
|
209
|
+
--stack-offset-y-2: -16px;
|
|
210
|
+
}
|
|
211
|
+
`;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { classNames, html, slotted, when } from '@genesislcap/web-core';
|
|
2
|
+
const headerTemplate = (prefix) => html `
|
|
3
|
+
<div class="header ${(x) => classNames(['visible', x.slottedNodes.length > 1])}">
|
|
4
|
+
${when((x) => x.showCount, html `
|
|
5
|
+
<span class="header-title">${(x) => x.slottedNodes.length} Notifications</span>
|
|
6
|
+
`)}
|
|
7
|
+
<div class="notification-header-buttons">
|
|
8
|
+
${when((x) => x.allowManualCollapse, html `
|
|
9
|
+
<${prefix}-button @click=${(x) => x.handleToggleCollapse()}>
|
|
10
|
+
${(x) => (x.stackCollapsed ? 'Expand' : 'Collapse')}
|
|
11
|
+
<${prefix}-icon
|
|
12
|
+
class="chevron-up ${(x) => classNames(['collapse', x.stackCollapsed])}"
|
|
13
|
+
name="chevron-up"></${prefix}-icon>
|
|
14
|
+
</${prefix}-button>
|
|
15
|
+
`)}
|
|
16
|
+
${when((x) => x.allowCloseAll, html `
|
|
17
|
+
<${prefix}-button @click=${(x) => x.handleCloseAll()}>
|
|
18
|
+
Close All
|
|
19
|
+
<${prefix}-icon name="xmark">
|
|
20
|
+
</${prefix}-icon>
|
|
21
|
+
</${prefix}-button>
|
|
22
|
+
`)}
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
`;
|
|
26
|
+
export const template = html `
|
|
27
|
+
${when((x) => x.allowCloseAll || x.allowManualCollapse, html `
|
|
28
|
+
${(x) => headerTemplate(x.designSystemPrefix)}
|
|
29
|
+
`)}
|
|
30
|
+
<div class="toast-container">
|
|
31
|
+
<slot ${slotted('slottedNodes')} @click="${(x) => x.handleContainerClick()}"></slot>
|
|
32
|
+
</div>
|
|
33
|
+
`;
|
package/dist/esm/index.js
CHANGED
|
@@ -1,4 +1,29 @@
|
|
|
1
|
+
import { getAllElements } from '@genesislcap/foundation-utils';
|
|
1
2
|
import { getNotificationContainer, showLoggerLogLevel } from '../notification-util';
|
|
3
|
+
const findNotifyContainer = (position) => {
|
|
4
|
+
return getAllElements(document.body).find((element) => element.tagName.toLowerCase() === 'notify-container' && element.position === position);
|
|
5
|
+
};
|
|
6
|
+
function configureDivContainer(notificationStructure, container) {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
container.style.position = 'fixed';
|
|
9
|
+
switch ((_b = (_a = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _a === void 0 ? void 0 : _a.toast) === null || _b === void 0 ? void 0 : _b.position) {
|
|
10
|
+
case 'top-left':
|
|
11
|
+
container.style.top = 'var(--nav-height, 0)';
|
|
12
|
+
container.style.left = '0';
|
|
13
|
+
break;
|
|
14
|
+
case 'bottom-left':
|
|
15
|
+
container.style.bottom = '0';
|
|
16
|
+
container.style.left = '0';
|
|
17
|
+
break;
|
|
18
|
+
case 'bottom-right':
|
|
19
|
+
container.style.bottom = '0';
|
|
20
|
+
container.style.right = '0';
|
|
21
|
+
break;
|
|
22
|
+
default:
|
|
23
|
+
container.style.top = 'var(--nav-height, 0)';
|
|
24
|
+
container.style.right = '0';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
2
27
|
/**
|
|
3
28
|
* Shows the notificationStructure
|
|
4
29
|
* @internal
|
|
@@ -8,29 +33,13 @@ import { getNotificationContainer, showLoggerLogLevel } from '../notification-ut
|
|
|
8
33
|
* @returns
|
|
9
34
|
* */
|
|
10
35
|
export const showToast = (notificationStructure, tagName, notificationContainer) => {
|
|
11
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
36
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
12
37
|
showLoggerLogLevel(notificationStructure);
|
|
13
38
|
const tagPrefix = tagName.split('-')[0];
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
case 'top-left':
|
|
19
|
-
container.style.top = 'var(--nav-height, 0)';
|
|
20
|
-
container.style.left = '0';
|
|
21
|
-
break;
|
|
22
|
-
case 'bottom-left':
|
|
23
|
-
container.style.bottom = '0';
|
|
24
|
-
container.style.left = '0';
|
|
25
|
-
break;
|
|
26
|
-
case 'bottom-right':
|
|
27
|
-
container.style.bottom = '0';
|
|
28
|
-
container.style.right = '0';
|
|
29
|
-
break;
|
|
30
|
-
default:
|
|
31
|
-
container.style.top = 'var(--nav-height, 0)';
|
|
32
|
-
container.style.right = '0';
|
|
33
|
-
}
|
|
39
|
+
const position = ((_b = (_a = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _a === void 0 ? void 0 : _a.toast) === null || _b === void 0 ? void 0 : _b.position) || 'top-right';
|
|
40
|
+
const container = (_c = notificationContainer !== null && notificationContainer !== void 0 ? notificationContainer : findNotifyContainer(position)) !== null && _c !== void 0 ? _c : getNotificationContainer('notify-container', tagName);
|
|
41
|
+
if (container && container.tagName.toLowerCase() !== 'notify-container') {
|
|
42
|
+
configureDivContainer(notificationStructure, container);
|
|
34
43
|
}
|
|
35
44
|
const toastNotify = document.createElement(`${tagPrefix}-toast`);
|
|
36
45
|
const toastTitle = document.createElement('div');
|
|
@@ -41,10 +50,10 @@ export const showToast = (notificationStructure, tagName, notificationContainer)
|
|
|
41
50
|
toastDetails.textContent = (notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.body) || '';
|
|
42
51
|
const toastDate = document.createElement('div');
|
|
43
52
|
toastDate.setAttribute('slot', 'date');
|
|
44
|
-
toastDate.textContent = ((
|
|
53
|
+
toastDate.textContent = ((_d = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.createdAt) === null || _d === void 0 ? void 0 : _d.toLocaleTimeString()) || '';
|
|
45
54
|
let toastBottom;
|
|
46
|
-
if (((
|
|
47
|
-
((
|
|
55
|
+
if (((_f = (_e = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _e === void 0 ? void 0 : _e.toast) === null || _f === void 0 ? void 0 : _f.buttons) &&
|
|
56
|
+
((_j = (_h = (_g = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _g === void 0 ? void 0 : _g.toast) === null || _h === void 0 ? void 0 : _h.buttons) === null || _j === void 0 ? void 0 : _j.length)) {
|
|
48
57
|
toastBottom = document.createElement('div');
|
|
49
58
|
toastBottom.setAttribute('slot', 'bottom');
|
|
50
59
|
notificationStructure.config.toast.buttons.forEach((button) => {
|
|
@@ -66,15 +75,15 @@ export const showToast = (notificationStructure, tagName, notificationContainer)
|
|
|
66
75
|
toastBottom.appendChild(buttonElement);
|
|
67
76
|
});
|
|
68
77
|
}
|
|
69
|
-
toastNotify.setAttribute('notify', ((
|
|
78
|
+
toastNotify.setAttribute('notify', ((_l = (_k = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _k === void 0 ? void 0 : _k.toast) === null || _l === void 0 ? void 0 : _l.type) || '');
|
|
70
79
|
if (notificationStructure.iconName) {
|
|
71
80
|
toastNotify.setAttribute('notification-icon', notificationStructure.iconName);
|
|
72
81
|
}
|
|
73
|
-
((
|
|
74
|
-
? toastNotify.setAttribute('auto-close', `${(
|
|
82
|
+
((_o = (_m = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _m === void 0 ? void 0 : _m.toast) === null || _o === void 0 ? void 0 : _o.autoClose)
|
|
83
|
+
? toastNotify.setAttribute('auto-close', `${(_q = (_p = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _p === void 0 ? void 0 : _p.toast) === null || _q === void 0 ? void 0 : _q.autoClose}`)
|
|
75
84
|
: '';
|
|
76
|
-
((
|
|
77
|
-
? toastNotify.setAttribute('close-timeout', `${(
|
|
85
|
+
((_s = (_r = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _r === void 0 ? void 0 : _r.toast) === null || _s === void 0 ? void 0 : _s.closeTimeout)
|
|
86
|
+
? toastNotify.setAttribute('close-timeout', `${(_u = (_t = notificationStructure === null || notificationStructure === void 0 ? void 0 : notificationStructure.config) === null || _t === void 0 ? void 0 : _t.toast) === null || _u === void 0 ? void 0 : _u.closeTimeout}`)
|
|
78
87
|
: '';
|
|
79
88
|
toastNotify.appendChild(toastTitle);
|
|
80
89
|
toastNotify.appendChild(toastDetails);
|
|
@@ -82,5 +91,5 @@ export const showToast = (notificationStructure, tagName, notificationContainer)
|
|
|
82
91
|
if (toastBottom) {
|
|
83
92
|
toastNotify.appendChild(toastBottom);
|
|
84
93
|
}
|
|
85
|
-
container.
|
|
94
|
+
container.prepend(toastNotify);
|
|
86
95
|
};
|