@justeattakeaway/pie-toast 0.1.0 → 0.2.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/custom-elements.json +304 -3
- package/dist/index.d.ts +137 -2
- package/dist/index.js +189 -9
- package/dist/react.d.ts +137 -2
- package/dist/react.js +19 -6
- package/package.json +2 -2
- package/src/defs.ts +68 -1
- package/src/index.ts +242 -8
- package/src/toast.scss +70 -0
package/custom-elements.json
CHANGED
|
@@ -11,8 +11,100 @@
|
|
|
11
11
|
{
|
|
12
12
|
"kind": "javascript-module",
|
|
13
13
|
"path": "src/defs.js",
|
|
14
|
-
"declarations": [
|
|
15
|
-
|
|
14
|
+
"declarations": [
|
|
15
|
+
{
|
|
16
|
+
"kind": "variable",
|
|
17
|
+
"name": "componentSelector",
|
|
18
|
+
"type": {
|
|
19
|
+
"text": "string"
|
|
20
|
+
},
|
|
21
|
+
"default": "'pie-toast'"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"kind": "variable",
|
|
25
|
+
"name": "componentClass",
|
|
26
|
+
"type": {
|
|
27
|
+
"text": "string"
|
|
28
|
+
},
|
|
29
|
+
"default": "'c-toast'"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"kind": "variable",
|
|
33
|
+
"name": "ON_TOAST_CLOSE_EVENT",
|
|
34
|
+
"default": "`${componentSelector}-close`",
|
|
35
|
+
"description": "Event name for when the toast is closed."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"kind": "variable",
|
|
39
|
+
"name": "ON_TOAST_OPEN_EVENT",
|
|
40
|
+
"default": "`${componentSelector}-open`",
|
|
41
|
+
"description": "Event name for when the toast is opened."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"kind": "variable",
|
|
45
|
+
"name": "ON_TOAST_LEADING_ACTION_CLICK_EVENT",
|
|
46
|
+
"default": "`${componentSelector}-leading-action-click`",
|
|
47
|
+
"description": "Event name for when the toast leading action is clicked."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"kind": "variable",
|
|
51
|
+
"name": "defaultProps",
|
|
52
|
+
"type": {
|
|
53
|
+
"text": "DefaultProps"
|
|
54
|
+
},
|
|
55
|
+
"default": "{\n isOpen: true,\n isDismissible: true,\n isMultiline: false,\n}"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"exports": [
|
|
59
|
+
{
|
|
60
|
+
"kind": "js",
|
|
61
|
+
"name": "componentSelector",
|
|
62
|
+
"declaration": {
|
|
63
|
+
"name": "componentSelector",
|
|
64
|
+
"module": "src/defs.js"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"kind": "js",
|
|
69
|
+
"name": "componentClass",
|
|
70
|
+
"declaration": {
|
|
71
|
+
"name": "componentClass",
|
|
72
|
+
"module": "src/defs.js"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"kind": "js",
|
|
77
|
+
"name": "ON_TOAST_CLOSE_EVENT",
|
|
78
|
+
"declaration": {
|
|
79
|
+
"name": "ON_TOAST_CLOSE_EVENT",
|
|
80
|
+
"module": "src/defs.js"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"kind": "js",
|
|
85
|
+
"name": "ON_TOAST_OPEN_EVENT",
|
|
86
|
+
"declaration": {
|
|
87
|
+
"name": "ON_TOAST_OPEN_EVENT",
|
|
88
|
+
"module": "src/defs.js"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"kind": "js",
|
|
93
|
+
"name": "ON_TOAST_LEADING_ACTION_CLICK_EVENT",
|
|
94
|
+
"declaration": {
|
|
95
|
+
"name": "ON_TOAST_LEADING_ACTION_CLICK_EVENT",
|
|
96
|
+
"module": "src/defs.js"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"kind": "js",
|
|
101
|
+
"name": "defaultProps",
|
|
102
|
+
"declaration": {
|
|
103
|
+
"name": "defaultProps",
|
|
104
|
+
"module": "src/defs.js"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
]
|
|
16
108
|
},
|
|
17
109
|
{
|
|
18
110
|
"kind": "javascript-module",
|
|
@@ -22,7 +114,216 @@
|
|
|
22
114
|
"kind": "class",
|
|
23
115
|
"description": "",
|
|
24
116
|
"name": "PieToast",
|
|
25
|
-
"members": [
|
|
117
|
+
"members": [
|
|
118
|
+
{
|
|
119
|
+
"kind": "field",
|
|
120
|
+
"name": "message",
|
|
121
|
+
"type": {
|
|
122
|
+
"text": "ToastProps['message']"
|
|
123
|
+
},
|
|
124
|
+
"privacy": "public",
|
|
125
|
+
"default": "''",
|
|
126
|
+
"attribute": "message"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"kind": "field",
|
|
130
|
+
"name": "isOpen",
|
|
131
|
+
"privacy": "public",
|
|
132
|
+
"attribute": "isOpen"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"kind": "field",
|
|
136
|
+
"name": "isDismissible",
|
|
137
|
+
"privacy": "public",
|
|
138
|
+
"attribute": "isDismissible"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"kind": "field",
|
|
142
|
+
"name": "isMultiline",
|
|
143
|
+
"privacy": "public",
|
|
144
|
+
"attribute": "isMultiline"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"kind": "field",
|
|
148
|
+
"name": "leadingAction",
|
|
149
|
+
"type": {
|
|
150
|
+
"text": "ToastProps['leadingAction']"
|
|
151
|
+
},
|
|
152
|
+
"privacy": "public",
|
|
153
|
+
"attribute": "leadingAction"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"kind": "field",
|
|
157
|
+
"name": "actionButton",
|
|
158
|
+
"type": {
|
|
159
|
+
"text": "HTMLElement | undefined"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"kind": "field",
|
|
164
|
+
"name": "_actionButtonOffset",
|
|
165
|
+
"type": {
|
|
166
|
+
"text": "number"
|
|
167
|
+
},
|
|
168
|
+
"privacy": "private",
|
|
169
|
+
"default": "0"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"kind": "field",
|
|
173
|
+
"name": "_messageAreaMaxWidth",
|
|
174
|
+
"type": {
|
|
175
|
+
"text": "number"
|
|
176
|
+
},
|
|
177
|
+
"privacy": "private",
|
|
178
|
+
"default": "0"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"kind": "method",
|
|
182
|
+
"name": "getMessageMaxWidth",
|
|
183
|
+
"privacy": "private",
|
|
184
|
+
"return": {
|
|
185
|
+
"type": {
|
|
186
|
+
"text": "number"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"parameters": [
|
|
190
|
+
{
|
|
191
|
+
"name": "hasIcon",
|
|
192
|
+
"type": {
|
|
193
|
+
"text": "boolean"
|
|
194
|
+
},
|
|
195
|
+
"description": "Indicates if the toast has an icon."
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"name": "isMultiline",
|
|
199
|
+
"type": {
|
|
200
|
+
"text": "boolean"
|
|
201
|
+
},
|
|
202
|
+
"description": "Indicates if the message is multiline."
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"name": "hasActionButton",
|
|
206
|
+
"type": {
|
|
207
|
+
"text": "boolean"
|
|
208
|
+
},
|
|
209
|
+
"description": "Indicates if the toast has an action button."
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"name": "hasCloseIcon",
|
|
213
|
+
"type": {
|
|
214
|
+
"text": "boolean"
|
|
215
|
+
},
|
|
216
|
+
"description": "Indicates if the toast has a close icon."
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
"description": "Calculates and returns the width of the message based on the toast properties."
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"kind": "method",
|
|
223
|
+
"name": "handleActionClick",
|
|
224
|
+
"privacy": "private",
|
|
225
|
+
"description": "It handle the action button action."
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"kind": "method",
|
|
229
|
+
"name": "renderActionButton",
|
|
230
|
+
"privacy": "private",
|
|
231
|
+
"return": {
|
|
232
|
+
"type": {
|
|
233
|
+
"text": "TemplateResult | typeof nothing"
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"parameters": [
|
|
237
|
+
{
|
|
238
|
+
"name": "action",
|
|
239
|
+
"type": {
|
|
240
|
+
"text": "ActionProps"
|
|
241
|
+
},
|
|
242
|
+
"description": "The action properties."
|
|
243
|
+
}
|
|
244
|
+
],
|
|
245
|
+
"description": "Render the action button depending on action type and its action."
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"kind": "method",
|
|
249
|
+
"name": "renderFooter",
|
|
250
|
+
"privacy": "private",
|
|
251
|
+
"description": "Template for the footer area.\nIt should display only when isMultiline is true as well if has action button.\nCalled within the main render function."
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"kind": "method",
|
|
255
|
+
"name": "renderCloseButton",
|
|
256
|
+
"privacy": "private",
|
|
257
|
+
"return": {
|
|
258
|
+
"type": {
|
|
259
|
+
"text": "TemplateResult"
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
"description": "Template for the close button element. Called within the\nmain render function."
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"kind": "method",
|
|
266
|
+
"name": "renderMessage",
|
|
267
|
+
"privacy": "private",
|
|
268
|
+
"return": {
|
|
269
|
+
"type": {
|
|
270
|
+
"text": "TemplateResult"
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"parameters": [
|
|
274
|
+
{
|
|
275
|
+
"name": "message",
|
|
276
|
+
"type": {
|
|
277
|
+
"text": "string"
|
|
278
|
+
},
|
|
279
|
+
"description": "The message to be displayed."
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"name": "messageAreaMaxWidth",
|
|
283
|
+
"type": {
|
|
284
|
+
"text": "number"
|
|
285
|
+
},
|
|
286
|
+
"description": "The maximum width of the message area calculated in the lifecycle method."
|
|
287
|
+
}
|
|
288
|
+
],
|
|
289
|
+
"description": "Template for the toast message. Called within the\nmain render function."
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"kind": "method",
|
|
293
|
+
"name": "closeToastComponent",
|
|
294
|
+
"privacy": "private",
|
|
295
|
+
"description": "Util method responsible to close the component.\nIt handles the action when user clicks in the close button and triggers an event when is executed."
|
|
296
|
+
}
|
|
297
|
+
],
|
|
298
|
+
"attributes": [
|
|
299
|
+
{
|
|
300
|
+
"name": "message",
|
|
301
|
+
"type": {
|
|
302
|
+
"text": "ToastProps['message']"
|
|
303
|
+
},
|
|
304
|
+
"default": "''",
|
|
305
|
+
"fieldName": "message"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"name": "isOpen",
|
|
309
|
+
"fieldName": "isOpen"
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"name": "isDismissible",
|
|
313
|
+
"fieldName": "isDismissible"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"name": "isMultiline",
|
|
317
|
+
"fieldName": "isMultiline"
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"name": "leadingAction",
|
|
321
|
+
"type": {
|
|
322
|
+
"text": "ToastProps['leadingAction']"
|
|
323
|
+
},
|
|
324
|
+
"fieldName": "leadingAction"
|
|
325
|
+
}
|
|
326
|
+
],
|
|
26
327
|
"mixins": [
|
|
27
328
|
{
|
|
28
329
|
"name": "RtlMixin",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,155 @@
|
|
|
1
|
+
import { ComponentDefaultPropsGeneric } from '@justeattakeaway/pie-webc-core';
|
|
1
2
|
import type { CSSResult } from 'lit';
|
|
2
3
|
import type { GenericConstructor } from '@justeattakeaway/pie-webc-core';
|
|
3
4
|
import type { LitElement } from 'lit';
|
|
5
|
+
import type { nothing } from 'lit';
|
|
6
|
+
import type { PropertyValues } from 'lit';
|
|
4
7
|
import type { RTLInterface } from '@justeattakeaway/pie-webc-core';
|
|
5
|
-
import type { TemplateResult } from 'lit
|
|
8
|
+
import type { TemplateResult } from 'lit';
|
|
9
|
+
|
|
10
|
+
export declare type ActionProps = {
|
|
11
|
+
/**
|
|
12
|
+
* The text to display inside the button.
|
|
13
|
+
*/
|
|
14
|
+
text: string;
|
|
15
|
+
/**
|
|
16
|
+
* The ARIA label for the button.
|
|
17
|
+
*/
|
|
18
|
+
ariaLabel?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export declare const componentClass = "c-toast";
|
|
22
|
+
|
|
23
|
+
export declare const componentSelector = "pie-toast";
|
|
24
|
+
|
|
25
|
+
export declare type DefaultProps = ComponentDefaultPropsGeneric<ToastProps, 'isOpen' | 'isDismissible' | 'isMultiline'>;
|
|
26
|
+
|
|
27
|
+
export declare const defaultProps: DefaultProps;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Event name for when the toast is closed.
|
|
31
|
+
*
|
|
32
|
+
* @constant
|
|
33
|
+
*/
|
|
34
|
+
export declare const ON_TOAST_CLOSE_EVENT: string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Event name for when the toast leading action is clicked.
|
|
38
|
+
*
|
|
39
|
+
* @constant
|
|
40
|
+
*/
|
|
41
|
+
export declare const ON_TOAST_LEADING_ACTION_CLICK_EVENT: string;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Event name for when the toast is opened.
|
|
45
|
+
*
|
|
46
|
+
* @constant
|
|
47
|
+
*/
|
|
48
|
+
export declare const ON_TOAST_OPEN_EVENT: string;
|
|
6
49
|
|
|
7
50
|
/**
|
|
8
51
|
* @tagname pie-toast
|
|
9
52
|
*/
|
|
10
53
|
export declare class PieToast extends PieToast_base implements ToastProps {
|
|
11
|
-
|
|
54
|
+
message: ToastProps['message'];
|
|
55
|
+
isOpen: any;
|
|
56
|
+
isDismissible: any;
|
|
57
|
+
isMultiline: any;
|
|
58
|
+
leadingAction: ToastProps['leadingAction'];
|
|
59
|
+
actionButton?: HTMLElement;
|
|
60
|
+
private _actionButtonOffset;
|
|
61
|
+
private _messageAreaMaxWidth;
|
|
12
62
|
static styles: CSSResult;
|
|
63
|
+
/**
|
|
64
|
+
* Calculates and returns the width of the message based on the toast properties.
|
|
65
|
+
*
|
|
66
|
+
* @param {boolean} hasIcon - Indicates if the toast has an icon.
|
|
67
|
+
* @param {boolean} isMultiline - Indicates if the message is multiline.
|
|
68
|
+
* @param {boolean} hasActionButton - Indicates if the toast has an action button.
|
|
69
|
+
* @param {boolean} hasCloseIcon - Indicates if the toast has a close icon.
|
|
70
|
+
*
|
|
71
|
+
* @returns {number} - The width of the message in pixels.
|
|
72
|
+
*/
|
|
73
|
+
private getMessageMaxWidth;
|
|
74
|
+
/**
|
|
75
|
+
* Lifecycle method executed when component is updated.
|
|
76
|
+
* It dispatches an event if toast is opened.
|
|
77
|
+
* It calculates _messageAreaMaxWidth
|
|
78
|
+
*/
|
|
79
|
+
protected updated(_changedProperties: PropertyValues<this>): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* It handle the action button action.
|
|
82
|
+
*
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
private handleActionClick;
|
|
86
|
+
/**
|
|
87
|
+
* Render the action button depending on action type and its action.
|
|
88
|
+
*
|
|
89
|
+
* @param {ActionProps} action - The action properties.
|
|
90
|
+
*
|
|
91
|
+
* @returns {TemplateResult | typeof nothing} - The rendered action button or nothing if the action text is not defined.
|
|
92
|
+
* @private
|
|
93
|
+
*/
|
|
94
|
+
private renderActionButton;
|
|
95
|
+
/**
|
|
96
|
+
* Template for the footer area.
|
|
97
|
+
* It should display only when isMultiline is true as well if has action button.
|
|
98
|
+
* Called within the main render function.
|
|
99
|
+
*
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
private renderFooter;
|
|
103
|
+
/**
|
|
104
|
+
* Template for the close button element. Called within the
|
|
105
|
+
* main render function.
|
|
106
|
+
*
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
109
|
+
private renderCloseButton;
|
|
110
|
+
/**
|
|
111
|
+
* Template for the toast message. Called within the
|
|
112
|
+
* main render function.
|
|
113
|
+
*
|
|
114
|
+
* @param {string} message - The message to be displayed.
|
|
115
|
+
* @param {number} messageAreaMaxWidth - The maximum width of the message area calculated in the lifecycle method.
|
|
116
|
+
*
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
private renderMessage;
|
|
120
|
+
/**
|
|
121
|
+
* Util method responsible to close the component.
|
|
122
|
+
* It handles the action when user clicks in the close button and triggers an event when is executed.
|
|
123
|
+
*
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
private closeToastComponent;
|
|
127
|
+
render(): TemplateResult<1> | typeof nothing;
|
|
13
128
|
}
|
|
14
129
|
|
|
15
130
|
declare const PieToast_base: GenericConstructor<RTLInterface> & typeof LitElement;
|
|
16
131
|
|
|
17
132
|
export declare interface ToastProps {
|
|
133
|
+
/**
|
|
134
|
+
* When true, the toast is set to be open and visible.
|
|
135
|
+
*/
|
|
136
|
+
isOpen?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* When true, allows dismissing the toast by clicking on the close button.
|
|
139
|
+
*/
|
|
140
|
+
isDismissible?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* The message content of the toast.
|
|
143
|
+
*/
|
|
144
|
+
message: string;
|
|
145
|
+
/**
|
|
146
|
+
* It allows the message content being displayed as multiline limited to three rows.
|
|
147
|
+
*/
|
|
148
|
+
isMultiline?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* The leading action for the toast.
|
|
151
|
+
*/
|
|
152
|
+
leadingAction?: ActionProps;
|
|
18
153
|
}
|
|
19
154
|
|
|
20
155
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,194 @@
|
|
|
1
|
-
import { LitElement as
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { LitElement as x, html as p, nothing as r, unsafeCSS as b } from "lit";
|
|
2
|
+
import { property as h, query as O } from "lit/decorators.js";
|
|
3
|
+
import { classMap as y } from "lit/directives/class-map.js";
|
|
4
|
+
import { RtlMixin as $, dispatchCustomEvent as g, defineCustomElement as A } from "@justeattakeaway/pie-webc-core";
|
|
5
|
+
import "@justeattakeaway/pie-icon-button";
|
|
6
|
+
import "@justeattakeaway/pie-icons-webc/dist/IconClose.js";
|
|
7
|
+
import "@justeattakeaway/pie-icons-webc/dist/IconPlaceholder.js";
|
|
8
|
+
import "@justeattakeaway/pie-button";
|
|
9
|
+
const M = `*,*:after,*:before{box-sizing:inherit}.c-toast{--toast-border-radius: var(--dt-radius-rounded-b);--toast-background-color: var(--dt-color-container-inverse);--toast-font-color: var(--dt-color-content-inverse);--toast-font-size: calc(var(--dt-font-body-s-size) * 1px);--toast-line-height: calc(var(--dt-font-body-s-line-height) * 1px);display:flex;flex-direction:column;justify-content:center;min-height:48px;max-height:122px;min-width:300px;max-width:420px;padding:var(--dt-spacing-a) var(--dt-spacing-c) var(--dt-spacing-a) var(--dt-spacing-d);border-radius:var(--toast-border-radius);gap:var(--dt-spacing-a);background-color:var(--toast-background-color);box-shadow:var(--dt-elevation-03);color:var(--toast-font-color);font-size:var(--toast-font-size);line-height:var(--toast-line-height)}.c-toast-contentArea{display:flex;gap:var(--dt-spacing-b);justify-content:space-between}.c-toast-messageArea{display:flex;align-items:center;gap:var(--dt-spacing-b);padding:calc(var(--dt-spacing-03) / 2) 0}.c-toast-messageArea span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.c-toast-messageArea.is-multiline{align-items:flex-start}.c-toast-messageArea.is-multiline span{max-height:60px;white-space:inherit;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical}.c-toast-actionsArea{display:flex;gap:var(--dt-spacing-b)}.c-toast-footer{display:flex;justify-content:flex-end}
|
|
10
|
+
`, o = "pie-toast", d = "c-toast", _ = `${o}-close`, C = `${o}-open`, w = `${o}-leading-action-click`, m = {
|
|
11
|
+
isOpen: !0,
|
|
12
|
+
isDismissible: !0,
|
|
13
|
+
isMultiline: !1
|
|
14
|
+
};
|
|
15
|
+
var B = Object.defineProperty, T = Object.getOwnPropertyDescriptor, l = (u, t, s, i) => {
|
|
16
|
+
for (var e = i > 1 ? void 0 : i ? T(t, s) : t, a = u.length - 1, c; a >= 0; a--)
|
|
17
|
+
(c = u[a]) && (e = (i ? c(t, s, e) : c(e)) || e);
|
|
18
|
+
return i && e && B(t, s, e), e;
|
|
19
|
+
};
|
|
20
|
+
class n extends $(x) {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments), this.message = "", this.isOpen = m.isOpen, this.isDismissible = m.isDismissible, this.isMultiline = m.isMultiline, this._actionButtonOffset = 0, this._messageAreaMaxWidth = 0;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Calculates and returns the width of the message based on the toast properties.
|
|
26
|
+
*
|
|
27
|
+
* @param {boolean} hasIcon - Indicates if the toast has an icon.
|
|
28
|
+
* @param {boolean} isMultiline - Indicates if the message is multiline.
|
|
29
|
+
* @param {boolean} hasActionButton - Indicates if the toast has an action button.
|
|
30
|
+
* @param {boolean} hasCloseIcon - Indicates if the toast has a close icon.
|
|
31
|
+
*
|
|
32
|
+
* @returns {number} - The width of the message in pixels.
|
|
33
|
+
*/
|
|
34
|
+
getMessageMaxWidth(t, s, i, e) {
|
|
35
|
+
let f = 0;
|
|
36
|
+
return t && (f += 20 + 8), !s && i && (f += this._actionButtonOffset + 8), e && (f += 32 + 8), 392 - f;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Lifecycle method executed when component is updated.
|
|
40
|
+
* It dispatches an event if toast is opened.
|
|
41
|
+
* It calculates _messageAreaMaxWidth
|
|
42
|
+
*/
|
|
43
|
+
async updated(t) {
|
|
44
|
+
var i;
|
|
45
|
+
t.has("isOpen") && this.isOpen && g(this, C, { targetNotification: this }), await this.updateComplete, this.actionButton && (this._actionButtonOffset = this.actionButton.offsetWidth);
|
|
46
|
+
const s = !0;
|
|
47
|
+
this._messageAreaMaxWidth = this.getMessageMaxWidth(s, this.isMultiline, !!((i = this.leadingAction) != null && i.text), this.isDismissible), (t.has("message") || t.has("isDismissible") || t.has("isMultiline") || t.has("leadingAction")) && this.requestUpdate();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* It handle the action button action.
|
|
51
|
+
*
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
handleActionClick() {
|
|
55
|
+
g(this, w, { targetNotification: this });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Render the action button depending on action type and its action.
|
|
59
|
+
*
|
|
60
|
+
* @param {ActionProps} action - The action properties.
|
|
61
|
+
*
|
|
62
|
+
* @returns {TemplateResult | typeof nothing} - The rendered action button or nothing if the action text is not defined.
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
renderActionButton(t) {
|
|
66
|
+
const { text: s, ariaLabel: i } = t;
|
|
67
|
+
return p`
|
|
68
|
+
<pie-button
|
|
69
|
+
variant="ghost-inverse"
|
|
70
|
+
size="xsmall"
|
|
71
|
+
aria-label="${i || r}"
|
|
72
|
+
@click="${() => this.handleActionClick()}"
|
|
73
|
+
data-test-id="${o}-leading-action"
|
|
74
|
+
type="button">
|
|
75
|
+
${s}
|
|
76
|
+
</pie-button>
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Template for the footer area.
|
|
81
|
+
* It should display only when isMultiline is true as well if has action button.
|
|
82
|
+
* Called within the main render function.
|
|
83
|
+
*
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
86
|
+
renderFooter() {
|
|
87
|
+
const { leadingAction: t } = this;
|
|
88
|
+
return p`
|
|
89
|
+
<footer class="${d}-footer" data-test-id="${o}-footer" >
|
|
90
|
+
${t ? this.renderActionButton(t) : r}
|
|
91
|
+
</footer>
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Template for the close button element. Called within the
|
|
96
|
+
* main render function.
|
|
97
|
+
*
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
renderCloseButton() {
|
|
101
|
+
return p`
|
|
102
|
+
<pie-icon-button
|
|
103
|
+
variant="ghost-inverse"
|
|
104
|
+
size="xsmall"
|
|
105
|
+
data-test-id="${o}-close"
|
|
106
|
+
@click="${this.closeToastComponent}">
|
|
107
|
+
<icon-close></icon-close>
|
|
108
|
+
</pie-icon-button>`;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Template for the toast message. Called within the
|
|
112
|
+
* main render function.
|
|
113
|
+
*
|
|
114
|
+
* @param {string} message - The message to be displayed.
|
|
115
|
+
* @param {number} messageAreaMaxWidth - The maximum width of the message area calculated in the lifecycle method.
|
|
116
|
+
*
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
renderMessage(t, s) {
|
|
120
|
+
return p`
|
|
121
|
+
<span style="max-width: ${s}px" data-test-id="${o}-message">
|
|
122
|
+
${t}
|
|
123
|
+
</span>
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Util method responsible to close the component.
|
|
128
|
+
* It handles the action when user clicks in the close button and triggers an event when is executed.
|
|
129
|
+
*
|
|
130
|
+
* @private
|
|
131
|
+
*/
|
|
132
|
+
closeToastComponent() {
|
|
133
|
+
this.isOpen = !1, g(this, _, { targetNotification: this });
|
|
134
|
+
}
|
|
6
135
|
render() {
|
|
7
|
-
|
|
136
|
+
const {
|
|
137
|
+
isOpen: t,
|
|
138
|
+
message: s,
|
|
139
|
+
isDismissible: i,
|
|
140
|
+
leadingAction: e,
|
|
141
|
+
isMultiline: a,
|
|
142
|
+
_messageAreaMaxWidth: c
|
|
143
|
+
} = this;
|
|
144
|
+
if (!t)
|
|
145
|
+
return r;
|
|
146
|
+
const v = {
|
|
147
|
+
[`${d}-messageArea`]: !0,
|
|
148
|
+
"is-multiline": a
|
|
149
|
+
};
|
|
150
|
+
return p`
|
|
151
|
+
<div data-test-id="${o}" class="${d}">
|
|
152
|
+
<div class="${d}-contentArea">
|
|
153
|
+
<div class="${y(v)}">
|
|
154
|
+
<icon-placeholder size="s"></icon-placeholder>
|
|
155
|
+
${s === "" ? r : this.renderMessage(s, c)}
|
|
156
|
+
</div>
|
|
157
|
+
<div class="${d}-actionsArea">
|
|
158
|
+
${!a && (e != null && e.text) ? this.renderActionButton(e) : r}
|
|
159
|
+
${i ? this.renderCloseButton() : r}
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
${a && (e != null && e.text) ? this.renderFooter() : r}
|
|
163
|
+
</div>`;
|
|
8
164
|
}
|
|
9
165
|
}
|
|
10
|
-
|
|
11
|
-
|
|
166
|
+
n.styles = b(M);
|
|
167
|
+
l([
|
|
168
|
+
h()
|
|
169
|
+
], n.prototype, "message", 2);
|
|
170
|
+
l([
|
|
171
|
+
h({ type: Boolean })
|
|
172
|
+
], n.prototype, "isOpen", 2);
|
|
173
|
+
l([
|
|
174
|
+
h({ type: Boolean })
|
|
175
|
+
], n.prototype, "isDismissible", 2);
|
|
176
|
+
l([
|
|
177
|
+
h({ type: Boolean })
|
|
178
|
+
], n.prototype, "isMultiline", 2);
|
|
179
|
+
l([
|
|
180
|
+
h({ type: Object })
|
|
181
|
+
], n.prototype, "leadingAction", 2);
|
|
182
|
+
l([
|
|
183
|
+
O("pie-button")
|
|
184
|
+
], n.prototype, "actionButton", 2);
|
|
185
|
+
A(o, n);
|
|
12
186
|
export {
|
|
13
|
-
|
|
187
|
+
_ as ON_TOAST_CLOSE_EVENT,
|
|
188
|
+
w as ON_TOAST_LEADING_ACTION_CLICK_EVENT,
|
|
189
|
+
C as ON_TOAST_OPEN_EVENT,
|
|
190
|
+
n as PieToast,
|
|
191
|
+
d as componentClass,
|
|
192
|
+
o as componentSelector,
|
|
193
|
+
m as defaultProps
|
|
14
194
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -1,9 +1,52 @@
|
|
|
1
|
+
import { ComponentDefaultPropsGeneric } from '@justeattakeaway/pie-webc-core';
|
|
1
2
|
import type { CSSResult } from 'lit';
|
|
2
3
|
import type { GenericConstructor } from '@justeattakeaway/pie-webc-core';
|
|
3
4
|
import type { LitElement } from 'lit';
|
|
5
|
+
import type { nothing } from 'lit';
|
|
6
|
+
import type { PropertyValues } from 'lit';
|
|
4
7
|
import * as React_2 from 'react';
|
|
5
8
|
import type { RTLInterface } from '@justeattakeaway/pie-webc-core';
|
|
6
|
-
import type { TemplateResult } from 'lit
|
|
9
|
+
import type { TemplateResult } from 'lit';
|
|
10
|
+
|
|
11
|
+
export declare type ActionProps = {
|
|
12
|
+
/**
|
|
13
|
+
* The text to display inside the button.
|
|
14
|
+
*/
|
|
15
|
+
text: string;
|
|
16
|
+
/**
|
|
17
|
+
* The ARIA label for the button.
|
|
18
|
+
*/
|
|
19
|
+
ariaLabel?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export declare const componentClass = "c-toast";
|
|
23
|
+
|
|
24
|
+
export declare const componentSelector = "pie-toast";
|
|
25
|
+
|
|
26
|
+
export declare type DefaultProps = ComponentDefaultPropsGeneric<ToastProps, 'isOpen' | 'isDismissible' | 'isMultiline'>;
|
|
27
|
+
|
|
28
|
+
export declare const defaultProps: DefaultProps;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Event name for when the toast is closed.
|
|
32
|
+
*
|
|
33
|
+
* @constant
|
|
34
|
+
*/
|
|
35
|
+
export declare const ON_TOAST_CLOSE_EVENT: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Event name for when the toast leading action is clicked.
|
|
39
|
+
*
|
|
40
|
+
* @constant
|
|
41
|
+
*/
|
|
42
|
+
export declare const ON_TOAST_LEADING_ACTION_CLICK_EVENT: string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Event name for when the toast is opened.
|
|
46
|
+
*
|
|
47
|
+
* @constant
|
|
48
|
+
*/
|
|
49
|
+
export declare const ON_TOAST_OPEN_EVENT: string;
|
|
7
50
|
|
|
8
51
|
export declare const PieToast: React_2.ForwardRefExoticComponent<ToastProps & React_2.RefAttributes<PieToast_2> & ReactBaseType>;
|
|
9
52
|
|
|
@@ -11,8 +54,80 @@ export declare const PieToast: React_2.ForwardRefExoticComponent<ToastProps & Re
|
|
|
11
54
|
* @tagname pie-toast
|
|
12
55
|
*/
|
|
13
56
|
declare class PieToast_2 extends PieToast_base implements ToastProps {
|
|
14
|
-
|
|
57
|
+
message: ToastProps['message'];
|
|
58
|
+
isOpen: any;
|
|
59
|
+
isDismissible: any;
|
|
60
|
+
isMultiline: any;
|
|
61
|
+
leadingAction: ToastProps['leadingAction'];
|
|
62
|
+
actionButton?: HTMLElement;
|
|
63
|
+
private _actionButtonOffset;
|
|
64
|
+
private _messageAreaMaxWidth;
|
|
15
65
|
static styles: CSSResult;
|
|
66
|
+
/**
|
|
67
|
+
* Calculates and returns the width of the message based on the toast properties.
|
|
68
|
+
*
|
|
69
|
+
* @param {boolean} hasIcon - Indicates if the toast has an icon.
|
|
70
|
+
* @param {boolean} isMultiline - Indicates if the message is multiline.
|
|
71
|
+
* @param {boolean} hasActionButton - Indicates if the toast has an action button.
|
|
72
|
+
* @param {boolean} hasCloseIcon - Indicates if the toast has a close icon.
|
|
73
|
+
*
|
|
74
|
+
* @returns {number} - The width of the message in pixels.
|
|
75
|
+
*/
|
|
76
|
+
private getMessageMaxWidth;
|
|
77
|
+
/**
|
|
78
|
+
* Lifecycle method executed when component is updated.
|
|
79
|
+
* It dispatches an event if toast is opened.
|
|
80
|
+
* It calculates _messageAreaMaxWidth
|
|
81
|
+
*/
|
|
82
|
+
protected updated(_changedProperties: PropertyValues<this>): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* It handle the action button action.
|
|
85
|
+
*
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
private handleActionClick;
|
|
89
|
+
/**
|
|
90
|
+
* Render the action button depending on action type and its action.
|
|
91
|
+
*
|
|
92
|
+
* @param {ActionProps} action - The action properties.
|
|
93
|
+
*
|
|
94
|
+
* @returns {TemplateResult | typeof nothing} - The rendered action button or nothing if the action text is not defined.
|
|
95
|
+
* @private
|
|
96
|
+
*/
|
|
97
|
+
private renderActionButton;
|
|
98
|
+
/**
|
|
99
|
+
* Template for the footer area.
|
|
100
|
+
* It should display only when isMultiline is true as well if has action button.
|
|
101
|
+
* Called within the main render function.
|
|
102
|
+
*
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
private renderFooter;
|
|
106
|
+
/**
|
|
107
|
+
* Template for the close button element. Called within the
|
|
108
|
+
* main render function.
|
|
109
|
+
*
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
private renderCloseButton;
|
|
113
|
+
/**
|
|
114
|
+
* Template for the toast message. Called within the
|
|
115
|
+
* main render function.
|
|
116
|
+
*
|
|
117
|
+
* @param {string} message - The message to be displayed.
|
|
118
|
+
* @param {number} messageAreaMaxWidth - The maximum width of the message area calculated in the lifecycle method.
|
|
119
|
+
*
|
|
120
|
+
* @private
|
|
121
|
+
*/
|
|
122
|
+
private renderMessage;
|
|
123
|
+
/**
|
|
124
|
+
* Util method responsible to close the component.
|
|
125
|
+
* It handles the action when user clicks in the close button and triggers an event when is executed.
|
|
126
|
+
*
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
private closeToastComponent;
|
|
130
|
+
render(): TemplateResult<1> | typeof nothing;
|
|
16
131
|
}
|
|
17
132
|
|
|
18
133
|
declare const PieToast_base: GenericConstructor<RTLInterface> & typeof LitElement;
|
|
@@ -20,6 +135,26 @@ declare const PieToast_base: GenericConstructor<RTLInterface> & typeof LitElemen
|
|
|
20
135
|
declare type ReactBaseType = React_2.HTMLAttributes<HTMLElement>;
|
|
21
136
|
|
|
22
137
|
export declare interface ToastProps {
|
|
138
|
+
/**
|
|
139
|
+
* When true, the toast is set to be open and visible.
|
|
140
|
+
*/
|
|
141
|
+
isOpen?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* When true, allows dismissing the toast by clicking on the close button.
|
|
144
|
+
*/
|
|
145
|
+
isDismissible?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* The message content of the toast.
|
|
148
|
+
*/
|
|
149
|
+
message: string;
|
|
150
|
+
/**
|
|
151
|
+
* It allows the message content being displayed as multiline limited to three rows.
|
|
152
|
+
*/
|
|
153
|
+
isMultiline?: boolean;
|
|
154
|
+
/**
|
|
155
|
+
* The leading action for the toast.
|
|
156
|
+
*/
|
|
157
|
+
leadingAction?: ActionProps;
|
|
23
158
|
}
|
|
24
159
|
|
|
25
160
|
export { }
|
package/dist/react.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
import * as t from "react";
|
|
2
|
-
import { createComponent as
|
|
3
|
-
import { PieToast as
|
|
2
|
+
import { createComponent as o } from "@lit/react";
|
|
3
|
+
import { PieToast as e } from "./index.js";
|
|
4
|
+
import { ON_TOAST_CLOSE_EVENT as P, ON_TOAST_LEADING_ACTION_CLICK_EVENT as l, ON_TOAST_OPEN_EVENT as f, componentClass as A, componentSelector as S, defaultProps as I } from "./index.js";
|
|
4
5
|
import "lit";
|
|
6
|
+
import "lit/decorators.js";
|
|
7
|
+
import "lit/directives/class-map.js";
|
|
5
8
|
import "@justeattakeaway/pie-webc-core";
|
|
6
|
-
|
|
9
|
+
import "@justeattakeaway/pie-icon-button";
|
|
10
|
+
import "@justeattakeaway/pie-icons-webc/dist/IconClose.js";
|
|
11
|
+
import "@justeattakeaway/pie-icons-webc/dist/IconPlaceholder.js";
|
|
12
|
+
import "@justeattakeaway/pie-button";
|
|
13
|
+
const m = o({
|
|
7
14
|
displayName: "PieToast",
|
|
8
|
-
elementClass:
|
|
15
|
+
elementClass: e,
|
|
9
16
|
react: t,
|
|
10
17
|
tagName: "pie-toast",
|
|
11
18
|
events: {}
|
|
12
|
-
}),
|
|
19
|
+
}), E = m;
|
|
13
20
|
export {
|
|
14
|
-
|
|
21
|
+
P as ON_TOAST_CLOSE_EVENT,
|
|
22
|
+
l as ON_TOAST_LEADING_ACTION_CLICK_EVENT,
|
|
23
|
+
f as ON_TOAST_OPEN_EVENT,
|
|
24
|
+
E as PieToast,
|
|
25
|
+
A as componentClass,
|
|
26
|
+
S as componentSelector,
|
|
27
|
+
I as defaultProps
|
|
15
28
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-toast",
|
|
3
3
|
"description": "PIE Design System Toast built using Web Components",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"cem-plugin-module-file-extensions": "0.0.5"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@justeattakeaway/pie-webc-core": "0.
|
|
43
|
+
"@justeattakeaway/pie-webc-core": "0.24.0"
|
|
44
44
|
},
|
|
45
45
|
"volta": {
|
|
46
46
|
"extends": "../../../package.json"
|
package/src/defs.ts
CHANGED
|
@@ -1,3 +1,70 @@
|
|
|
1
|
+
import { type ComponentDefaultPropsGeneric } from '@justeattakeaway/pie-webc-core';
|
|
2
|
+
|
|
1
3
|
// TODO - please remove the eslint disable comment below when you add props to this interface
|
|
2
4
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
3
|
-
export
|
|
5
|
+
export type ActionProps = {
|
|
6
|
+
/**
|
|
7
|
+
* The text to display inside the button.
|
|
8
|
+
*/
|
|
9
|
+
text: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The ARIA label for the button.
|
|
13
|
+
*/
|
|
14
|
+
ariaLabel?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export interface ToastProps {
|
|
18
|
+
/**
|
|
19
|
+
* When true, the toast is set to be open and visible.
|
|
20
|
+
*/
|
|
21
|
+
isOpen?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* When true, allows dismissing the toast by clicking on the close button.
|
|
24
|
+
*/
|
|
25
|
+
isDismissible?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The message content of the toast.
|
|
28
|
+
*/
|
|
29
|
+
message: string;
|
|
30
|
+
/**
|
|
31
|
+
* It allows the message content being displayed as multiline limited to three rows.
|
|
32
|
+
*/
|
|
33
|
+
isMultiline?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The leading action for the toast.
|
|
36
|
+
*/
|
|
37
|
+
leadingAction?: ActionProps;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const componentSelector = 'pie-toast';
|
|
41
|
+
export const componentClass = 'c-toast';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Event name for when the toast is closed.
|
|
45
|
+
*
|
|
46
|
+
* @constant
|
|
47
|
+
*/
|
|
48
|
+
export const ON_TOAST_CLOSE_EVENT = `${componentSelector}-close`;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Event name for when the toast is opened.
|
|
52
|
+
*
|
|
53
|
+
* @constant
|
|
54
|
+
*/
|
|
55
|
+
export const ON_TOAST_OPEN_EVENT = `${componentSelector}-open`;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Event name for when the toast leading action is clicked.
|
|
59
|
+
*
|
|
60
|
+
* @constant
|
|
61
|
+
*/
|
|
62
|
+
export const ON_TOAST_LEADING_ACTION_CLICK_EVENT = `${componentSelector}-leading-action-click`;
|
|
63
|
+
|
|
64
|
+
export type DefaultProps = ComponentDefaultPropsGeneric<ToastProps, 'isOpen' | 'isDismissible' | 'isMultiline'>;
|
|
65
|
+
|
|
66
|
+
export const defaultProps: DefaultProps = {
|
|
67
|
+
isOpen: true,
|
|
68
|
+
isDismissible: true,
|
|
69
|
+
isMultiline: false,
|
|
70
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,24 +1,258 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
LitElement,
|
|
3
|
+
html,
|
|
4
|
+
unsafeCSS,
|
|
5
|
+
nothing,
|
|
6
|
+
type TemplateResult,
|
|
7
|
+
type PropertyValues,
|
|
8
|
+
} from 'lit';
|
|
9
|
+
import { property, query } from 'lit/decorators.js';
|
|
10
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
11
|
+
import { RtlMixin, defineCustomElement, dispatchCustomEvent } from '@justeattakeaway/pie-webc-core';
|
|
12
|
+
import '@justeattakeaway/pie-icon-button';
|
|
13
|
+
import '@justeattakeaway/pie-icons-webc/dist/IconClose.js';
|
|
14
|
+
import '@justeattakeaway/pie-icons-webc/dist/IconPlaceholder.js';
|
|
15
|
+
import '@justeattakeaway/pie-button';
|
|
3
16
|
|
|
4
17
|
import styles from './toast.scss?inline';
|
|
5
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
ToastProps,
|
|
20
|
+
componentSelector,
|
|
21
|
+
componentClass,
|
|
22
|
+
ActionProps,
|
|
23
|
+
ON_TOAST_CLOSE_EVENT,
|
|
24
|
+
ON_TOAST_OPEN_EVENT,
|
|
25
|
+
ON_TOAST_LEADING_ACTION_CLICK_EVENT,
|
|
26
|
+
defaultProps,
|
|
27
|
+
} from './defs';
|
|
6
28
|
|
|
7
29
|
// Valid values available to consumers
|
|
8
30
|
export * from './defs';
|
|
9
31
|
|
|
10
|
-
const componentSelector = 'pie-toast';
|
|
11
|
-
|
|
12
32
|
/**
|
|
13
33
|
* @tagname pie-toast
|
|
14
34
|
*/
|
|
15
35
|
export class PieToast extends RtlMixin(LitElement) implements ToastProps {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
36
|
+
@property()
|
|
37
|
+
public message: ToastProps['message'] = '';
|
|
38
|
+
|
|
39
|
+
@property({ type: Boolean })
|
|
40
|
+
public isOpen = defaultProps.isOpen;
|
|
41
|
+
|
|
42
|
+
@property({ type: Boolean })
|
|
43
|
+
public isDismissible = defaultProps.isDismissible;
|
|
44
|
+
|
|
45
|
+
@property({ type: Boolean })
|
|
46
|
+
public isMultiline = defaultProps.isMultiline;
|
|
47
|
+
|
|
48
|
+
@property({ type: Object })
|
|
49
|
+
public leadingAction: ToastProps['leadingAction'];
|
|
50
|
+
|
|
51
|
+
@query('pie-button') actionButton?: HTMLElement;
|
|
52
|
+
|
|
53
|
+
private _actionButtonOffset = 0;
|
|
54
|
+
|
|
55
|
+
private _messageAreaMaxWidth = 0;
|
|
19
56
|
|
|
20
57
|
// Renders a `CSSResult` generated from SCSS by Vite
|
|
21
58
|
static styles = unsafeCSS(styles);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Calculates and returns the width of the message based on the toast properties.
|
|
62
|
+
*
|
|
63
|
+
* @param {boolean} hasIcon - Indicates if the toast has an icon.
|
|
64
|
+
* @param {boolean} isMultiline - Indicates if the message is multiline.
|
|
65
|
+
* @param {boolean} hasActionButton - Indicates if the toast has an action button.
|
|
66
|
+
* @param {boolean} hasCloseIcon - Indicates if the toast has a close icon.
|
|
67
|
+
*
|
|
68
|
+
* @returns {number} - The width of the message in pixels.
|
|
69
|
+
*/
|
|
70
|
+
private getMessageMaxWidth (
|
|
71
|
+
hasIcon: boolean,
|
|
72
|
+
isMultiline: boolean,
|
|
73
|
+
hasActionButton: boolean,
|
|
74
|
+
hasCloseIcon: boolean,
|
|
75
|
+
): number {
|
|
76
|
+
const iconOffset = 20;
|
|
77
|
+
const closeIconOffset = 32;
|
|
78
|
+
const gap = 8;
|
|
79
|
+
const toastMaxWidthWithoutPadding = 392;
|
|
80
|
+
|
|
81
|
+
let offset = 0;
|
|
82
|
+
|
|
83
|
+
if (hasIcon) {
|
|
84
|
+
offset += iconOffset + gap;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!isMultiline && hasActionButton) {
|
|
88
|
+
offset += this._actionButtonOffset + gap;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (hasCloseIcon) {
|
|
92
|
+
offset += closeIconOffset + gap;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return toastMaxWidthWithoutPadding - offset;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Lifecycle method executed when component is updated.
|
|
100
|
+
* It dispatches an event if toast is opened.
|
|
101
|
+
* It calculates _messageAreaMaxWidth
|
|
102
|
+
*/
|
|
103
|
+
protected async updated (_changedProperties: PropertyValues<this>) {
|
|
104
|
+
if (_changedProperties.has('isOpen') && this.isOpen) {
|
|
105
|
+
dispatchCustomEvent(this, ON_TOAST_OPEN_EVENT, { targetNotification: this });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
await this.updateComplete;
|
|
109
|
+
|
|
110
|
+
if (this.actionButton) {
|
|
111
|
+
this._actionButtonOffset = this.actionButton.offsetWidth;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Temporary const. This will be removed when we implement variants.
|
|
115
|
+
const hasIcon = true;
|
|
116
|
+
|
|
117
|
+
this._messageAreaMaxWidth = this.getMessageMaxWidth(hasIcon, this.isMultiline, !!this.leadingAction?.text, this.isDismissible);
|
|
118
|
+
|
|
119
|
+
if (
|
|
120
|
+
_changedProperties.has('message') ||
|
|
121
|
+
_changedProperties.has('isDismissible') ||
|
|
122
|
+
_changedProperties.has('isMultiline') ||
|
|
123
|
+
_changedProperties.has('leadingAction')) {
|
|
124
|
+
this.requestUpdate();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* It handle the action button action.
|
|
130
|
+
*
|
|
131
|
+
* @private
|
|
132
|
+
*/
|
|
133
|
+
private handleActionClick () {
|
|
134
|
+
dispatchCustomEvent(this, ON_TOAST_LEADING_ACTION_CLICK_EVENT, { targetNotification: this });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Render the action button depending on action type and its action.
|
|
139
|
+
*
|
|
140
|
+
* @param {ActionProps} action - The action properties.
|
|
141
|
+
*
|
|
142
|
+
* @returns {TemplateResult | typeof nothing} - The rendered action button or nothing if the action text is not defined.
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
145
|
+
private renderActionButton (action: ActionProps) : TemplateResult | typeof nothing {
|
|
146
|
+
const { text, ariaLabel } = action;
|
|
147
|
+
|
|
148
|
+
return html`
|
|
149
|
+
<pie-button
|
|
150
|
+
variant="ghost-inverse"
|
|
151
|
+
size="xsmall"
|
|
152
|
+
aria-label="${ariaLabel || nothing}"
|
|
153
|
+
@click="${() => this.handleActionClick()}"
|
|
154
|
+
data-test-id="${componentSelector}-leading-action"
|
|
155
|
+
type="button">
|
|
156
|
+
${text}
|
|
157
|
+
</pie-button>
|
|
158
|
+
`;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Template for the footer area.
|
|
163
|
+
* It should display only when isMultiline is true as well if has action button.
|
|
164
|
+
* Called within the main render function.
|
|
165
|
+
*
|
|
166
|
+
* @private
|
|
167
|
+
*/
|
|
168
|
+
private renderFooter () {
|
|
169
|
+
const { leadingAction } = this;
|
|
170
|
+
return html`
|
|
171
|
+
<footer class="${componentClass}-footer" data-test-id="${componentSelector}-footer" >
|
|
172
|
+
${leadingAction ? this.renderActionButton(leadingAction) : nothing}
|
|
173
|
+
</footer>
|
|
174
|
+
`;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Template for the close button element. Called within the
|
|
179
|
+
* main render function.
|
|
180
|
+
*
|
|
181
|
+
* @private
|
|
182
|
+
*/
|
|
183
|
+
private renderCloseButton (): TemplateResult {
|
|
184
|
+
return html`
|
|
185
|
+
<pie-icon-button
|
|
186
|
+
variant="ghost-inverse"
|
|
187
|
+
size="xsmall"
|
|
188
|
+
data-test-id="${componentSelector}-close"
|
|
189
|
+
@click="${this.closeToastComponent}">
|
|
190
|
+
<icon-close></icon-close>
|
|
191
|
+
</pie-icon-button>`;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Template for the toast message. Called within the
|
|
196
|
+
* main render function.
|
|
197
|
+
*
|
|
198
|
+
* @param {string} message - The message to be displayed.
|
|
199
|
+
* @param {number} messageAreaMaxWidth - The maximum width of the message area calculated in the lifecycle method.
|
|
200
|
+
*
|
|
201
|
+
* @private
|
|
202
|
+
*/
|
|
203
|
+
private renderMessage (message: string, messageAreaMaxWidth: number): TemplateResult {
|
|
204
|
+
return html`
|
|
205
|
+
<span style="max-width: ${messageAreaMaxWidth}px" data-test-id="${componentSelector}-message">
|
|
206
|
+
${message}
|
|
207
|
+
</span>
|
|
208
|
+
`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Util method responsible to close the component.
|
|
213
|
+
* It handles the action when user clicks in the close button and triggers an event when is executed.
|
|
214
|
+
*
|
|
215
|
+
* @private
|
|
216
|
+
*/
|
|
217
|
+
private closeToastComponent () {
|
|
218
|
+
this.isOpen = false;
|
|
219
|
+
dispatchCustomEvent(this, ON_TOAST_CLOSE_EVENT, { targetNotification: this });
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
render () {
|
|
223
|
+
const {
|
|
224
|
+
isOpen,
|
|
225
|
+
message,
|
|
226
|
+
isDismissible,
|
|
227
|
+
leadingAction,
|
|
228
|
+
isMultiline,
|
|
229
|
+
_messageAreaMaxWidth,
|
|
230
|
+
} = this;
|
|
231
|
+
|
|
232
|
+
if (!isOpen) {
|
|
233
|
+
return nothing;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const messageAreaClasses = {
|
|
237
|
+
[`${componentClass}-messageArea`]: true,
|
|
238
|
+
'is-multiline': isMultiline,
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
return html`
|
|
242
|
+
<div data-test-id="${componentSelector}" class="${componentClass}">
|
|
243
|
+
<div class="${componentClass}-contentArea">
|
|
244
|
+
<div class="${classMap(messageAreaClasses)}">
|
|
245
|
+
<icon-placeholder size="s"></icon-placeholder>
|
|
246
|
+
${message === '' ? nothing : this.renderMessage(message, _messageAreaMaxWidth)}
|
|
247
|
+
</div>
|
|
248
|
+
<div class="${componentClass}-actionsArea">
|
|
249
|
+
${!isMultiline && leadingAction?.text ? this.renderActionButton(leadingAction) : nothing}
|
|
250
|
+
${isDismissible ? this.renderCloseButton() : nothing}
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
${isMultiline && leadingAction?.text ? this.renderFooter() : nothing}
|
|
254
|
+
</div>`;
|
|
255
|
+
}
|
|
22
256
|
}
|
|
23
257
|
|
|
24
258
|
defineCustomElement(componentSelector, PieToast);
|
package/src/toast.scss
CHANGED
|
@@ -1 +1,71 @@
|
|
|
1
1
|
@use '@justeattakeaway/pie-css/scss' as p;
|
|
2
|
+
|
|
3
|
+
.c-toast {
|
|
4
|
+
--toast-border-radius: var(--dt-radius-rounded-b);
|
|
5
|
+
--toast-background-color: var(--dt-color-container-inverse);
|
|
6
|
+
--toast-font-color: var(--dt-color-content-inverse);
|
|
7
|
+
--toast-font-size: #{p.font-size(--dt-font-body-s-size)};
|
|
8
|
+
--toast-line-height: #{p.line-height(--dt-font-body-s-line-height)};
|
|
9
|
+
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
min-height: 48px;
|
|
14
|
+
max-height: 122px;
|
|
15
|
+
min-width: 300px;
|
|
16
|
+
max-width: 420px;
|
|
17
|
+
|
|
18
|
+
padding: var(--dt-spacing-a) var(--dt-spacing-c) var(--dt-spacing-a) var(--dt-spacing-d);
|
|
19
|
+
border-radius: var(--toast-border-radius);
|
|
20
|
+
gap: var(--dt-spacing-a);
|
|
21
|
+
background-color: var(--toast-background-color);
|
|
22
|
+
box-shadow: var(--dt-elevation-03);
|
|
23
|
+
color: var(--toast-font-color);
|
|
24
|
+
font-size: var(--toast-font-size);
|
|
25
|
+
line-height: var(--toast-line-height);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.c-toast-contentArea {
|
|
29
|
+
display: flex;
|
|
30
|
+
gap: var(--dt-spacing-b);
|
|
31
|
+
justify-content: space-between;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.c-toast-messageArea {
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
gap: var(--dt-spacing-b);
|
|
38
|
+
padding: calc(var(--dt-spacing-03) / 2) 0;
|
|
39
|
+
|
|
40
|
+
span {
|
|
41
|
+
text-overflow: ellipsis;
|
|
42
|
+
white-space: nowrap;
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&.is-multiline {
|
|
47
|
+
align-items: flex-start;
|
|
48
|
+
|
|
49
|
+
span {
|
|
50
|
+
max-height: 60px;
|
|
51
|
+
white-space: inherit;
|
|
52
|
+
|
|
53
|
+
// text-overflow: ellipsis; for multiline lines only works using webkit prefix
|
|
54
|
+
/* stylelint-disable */
|
|
55
|
+
display: -webkit-box;
|
|
56
|
+
/* stylelint-enable */
|
|
57
|
+
-webkit-line-clamp: 3;
|
|
58
|
+
-webkit-box-orient: vertical;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.c-toast-actionsArea {
|
|
64
|
+
display: flex;
|
|
65
|
+
gap: var(--dt-spacing-b);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.c-toast-footer {
|
|
69
|
+
display: flex;
|
|
70
|
+
justify-content: flex-end;
|
|
71
|
+
}
|