@kubex/zinc 1.0.7 → 1.0.8
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/custom-elements.json +318 -10
- package/dist/vscode.html-custom-data.json +33 -5
- package/dist/web-types.json +80 -12
- package/dist/zn.d.ts +53 -3
- package/dist/zn.min.js +371 -311
- package/docs/data/products-table.json +203 -0
- package/docs/pages/components/button.md +25 -0
- package/docs/pages/components/data-table.md +21 -0
- package/docs/pages/components/header.md +7 -0
- package/docs/pages/components/order-table.md +82 -5
- package/package.json +1 -1
- package/src/components/button/button.component.ts +168 -10
- package/src/components/button/button.scss +115 -0
- package/src/components/content-block/content-block.component.ts +18 -7
- package/src/components/content-block/content-block.scss +4 -2
- package/src/components/data-select/data-select.component.ts +0 -1
- package/src/components/data-table/data-table.component.ts +112 -20
- package/src/components/data-table/data-table.scss +14 -3
- package/src/components/editor/editor.scss +1 -0
- package/src/components/expanding-action/expanding-action.component.ts +1 -1
- package/src/components/header/header.component.ts +8 -2
- package/src/components/header/header.scss +5 -1
- package/src/components/linked-select/linked-select.component.ts +1 -0
- package/src/components/menu/menu.component.ts +0 -1
- package/src/components/navbar/navbar.component.ts +1 -1
- package/src/components/note/note.component.ts +70 -2
- package/src/components/note/note.scss +26 -4
- package/src/components/order-table/order-table.component.ts +49 -28
- package/src/components/panel/panel.component.ts +3 -1
- package/src/components/rating/rating.component.ts +10 -9
- package/src/components/rating/rating.scss +15 -1
|
@@ -28,6 +28,209 @@
|
|
|
28
28
|
"text": "99"
|
|
29
29
|
}
|
|
30
30
|
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "2",
|
|
34
|
+
"cells": [
|
|
35
|
+
{
|
|
36
|
+
"column": "name",
|
|
37
|
+
"text": "Furminator deShedding Tool for Small Dogs"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"column": "category",
|
|
41
|
+
"text": "pets"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"column": "price",
|
|
45
|
+
"text": "£28.99"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"column": "discountPercentage",
|
|
49
|
+
"text": "6.19"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"column": "rating",
|
|
53
|
+
"text": "9.32"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"column": "stock",
|
|
57
|
+
"text": "61"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"id": "3",
|
|
63
|
+
"cells": [
|
|
64
|
+
{
|
|
65
|
+
"column": "name",
|
|
66
|
+
"text": "HP Pavilion 15-DK1056WM"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"column": "category",
|
|
70
|
+
"text": "laptops"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"column": "price",
|
|
74
|
+
"text": "£749.99"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"column": "discountPercentage",
|
|
78
|
+
"text": "10.23"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"column": "rating",
|
|
82
|
+
"text": "9.43"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"column": "stock",
|
|
86
|
+
"text": "89"
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "4",
|
|
92
|
+
"cells": [
|
|
93
|
+
{
|
|
94
|
+
"column": "name",
|
|
95
|
+
"text": "Samsung Galaxy Book S"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"column": "category",
|
|
99
|
+
"text": "laptops"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"column": "price",
|
|
103
|
+
"text": "£819.99"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"column": "discountPercentage",
|
|
107
|
+
"text": "4.15"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"column": "rating",
|
|
111
|
+
"text": "9.57"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"column": "stock",
|
|
115
|
+
"text": "115"
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "5",
|
|
121
|
+
"cells": [
|
|
122
|
+
{
|
|
123
|
+
"column": "name",
|
|
124
|
+
"text": "Infinix INBOOK"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"column": "category",
|
|
128
|
+
"text": "laptops"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"column": "price",
|
|
132
|
+
"text": "£409.99"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"column": "discountPercentage",
|
|
136
|
+
"text": "11.54"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"column": "rating",
|
|
140
|
+
"text": "8.91"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"column": "stock",
|
|
144
|
+
"text": "96"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": "6",
|
|
150
|
+
"cells": [
|
|
151
|
+
{
|
|
152
|
+
"column": "name",
|
|
153
|
+
"text": "HP Pavilion 15-DK1056WM"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"column": "category",
|
|
157
|
+
"text": "laptops"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"column": "price",
|
|
161
|
+
"text": "£749.99"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"column": "discountPercentage",
|
|
165
|
+
"text": "10.23"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"column": "rating",
|
|
169
|
+
"text": "9.43"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"column": "stock",
|
|
173
|
+
"text": "89"
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"id": "7",
|
|
179
|
+
"cells": [
|
|
180
|
+
{
|
|
181
|
+
"column": "name",
|
|
182
|
+
"text": "Samsung Galaxy Book S"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"column": "category",
|
|
186
|
+
"text": "laptops"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"column": "price",
|
|
190
|
+
"text": "£819.99"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"column": "discountPercentage",
|
|
194
|
+
"text": "4.15"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"column": "rating",
|
|
198
|
+
"text": "9.57"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"column": "stock",
|
|
202
|
+
"text": "115"
|
|
203
|
+
}
|
|
204
|
+
]
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"id": "8",
|
|
208
|
+
"cells": [
|
|
209
|
+
{
|
|
210
|
+
"column": "name",
|
|
211
|
+
"text": "Infinix INBOOK"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"column": "category",
|
|
215
|
+
"text": "pets"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"column": "price",
|
|
219
|
+
"text": "£409.99"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"column": "discountPercentage",
|
|
223
|
+
"text": "11.54"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"column": "rating",
|
|
227
|
+
"text": "8.91"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"column": "stock",
|
|
231
|
+
"text": "96"
|
|
232
|
+
}
|
|
233
|
+
]
|
|
31
234
|
}
|
|
32
235
|
],
|
|
33
236
|
"perPage": 10,
|
|
@@ -11,6 +11,31 @@ layout: component
|
|
|
11
11
|
|
|
12
12
|
## Examples
|
|
13
13
|
|
|
14
|
+
### Auto Click
|
|
15
|
+
|
|
16
|
+
The `auto-click` attribute can be added to a button to make it automatically click after a given time
|
|
17
|
+
|
|
18
|
+
```html:preview
|
|
19
|
+
<zn-button auto-click>
|
|
20
|
+
Test Auto Button
|
|
21
|
+
</zn-button auto-click>
|
|
22
|
+
|
|
23
|
+
<br>
|
|
24
|
+
<br>
|
|
25
|
+
|
|
26
|
+
<zn-button color="transparent" auto-click auto-click-delay="5000">
|
|
27
|
+
Test Auto Button
|
|
28
|
+
|
|
29
|
+
<zn-button
|
|
30
|
+
slot="cancel"
|
|
31
|
+
icon="close"
|
|
32
|
+
icon-size="18"
|
|
33
|
+
type="button"
|
|
34
|
+
color="transparent"
|
|
35
|
+
></zn-button>
|
|
36
|
+
</zn-button auto-click>
|
|
37
|
+
```
|
|
38
|
+
|
|
14
39
|
### Variants
|
|
15
40
|
|
|
16
41
|
Use the `color` attribute to set the button's color.
|
|
@@ -30,6 +30,27 @@ fullWidth: true
|
|
|
30
30
|
|
|
31
31
|
## Examples
|
|
32
32
|
|
|
33
|
+
### Grouping Split Tables
|
|
34
|
+
|
|
35
|
+
Splits table into groups based on a specified column. (Will request all data upfront)
|
|
36
|
+
|
|
37
|
+
```html:preview
|
|
38
|
+
|
|
39
|
+
<zn-data-table data-uri="/data/products-table.json" method="GET" group="category"
|
|
40
|
+
headers="[{"key":"name","label":"Name"},
|
|
41
|
+
{"key":"category","label":"Category"},
|
|
42
|
+
{"key":"price","label":"Price"},
|
|
43
|
+
{"key":"discountPercentage","label":"Discount %"},
|
|
44
|
+
{"key":"stock","label":"Stock"},
|
|
45
|
+
{"key":"rating","label":"Rating"}]">
|
|
46
|
+
|
|
47
|
+
<zn-empty-state slot="empty-state" icon="inventory_2" caption="No products found">
|
|
48
|
+
<p>Use the filters to search for products</p>
|
|
49
|
+
</zn-empty-state>
|
|
50
|
+
|
|
51
|
+
</zn-data-table>
|
|
52
|
+
```
|
|
53
|
+
|
|
33
54
|
### Filter-top Slot
|
|
34
55
|
|
|
35
56
|
Add complex filtering options to the top of the table using the `filter-top` slot.
|
|
@@ -37,6 +37,13 @@ layout: component
|
|
|
37
37
|
<zn-header caption="John Jones" description="This is the description of the header"></zn-header>
|
|
38
38
|
</div>
|
|
39
39
|
```
|
|
40
|
+
### Simple Header with Icon
|
|
41
|
+
|
|
42
|
+
```html:preview
|
|
43
|
+
<div style="background-color: #f5f5f5; padding: 20px;">
|
|
44
|
+
<zn-header icon="person" caption="John Jones" description="This is the description of the header"></zn-header>
|
|
45
|
+
</div>
|
|
46
|
+
```
|
|
40
47
|
|
|
41
48
|
|
|
42
49
|
### Simple Header with actions
|
|
@@ -1,21 +1,98 @@
|
|
|
1
1
|
---
|
|
2
2
|
meta:
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
title: OrderTable
|
|
4
|
+
description:
|
|
5
5
|
layout: component
|
|
6
|
+
fullWidth: true
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
```html:preview
|
|
9
|
-
<zn-order-table
|
|
10
|
+
<zn-order-table data="{
|
|
11
|
+
"headers": ["Product", "SKU", "Quantity", "Unit Price", "Subtotal", "Total"],
|
|
12
|
+
"items": [
|
|
13
|
+
{
|
|
14
|
+
"caption": "Electronics",
|
|
15
|
+
"summary": "Devices and accessories",
|
|
16
|
+
"data": [],
|
|
17
|
+
"sub": [
|
|
18
|
+
{
|
|
19
|
+
"caption": "Wireless Headphones",
|
|
20
|
+
"summary": "Noise-cancelling over-ear model",
|
|
21
|
+
"data": ["ELC-1021", "Wireless Headphones", "1", "£120.00", "£120.00"]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"caption": "USB-C Charger",
|
|
25
|
+
"summary": "Fast-charging 65W adapter",
|
|
26
|
+
"data": ["ELC-3054", "USB-C Charger", "2", "£25.00", "£50.00"]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"caption": "Bluetooth Speaker",
|
|
30
|
+
"summary": "Portable waterproof mini speaker",
|
|
31
|
+
"data": ["ELC-4092", "Bluetooth Speaker", "1", "£55.00", "£55.00"]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"caption": "Home & Kitchen",
|
|
37
|
+
"summary": "Appliances and essentials",
|
|
38
|
+
"data": [],
|
|
39
|
+
"sub": [
|
|
40
|
+
{
|
|
41
|
+
"caption": "Electric Kettle",
|
|
42
|
+
"summary": "1.7L stainless steel kettle",
|
|
43
|
+
"data": ["HMK-2210", "Electric Kettle", "1", "£35.00", "£35.00"]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"caption": "Coffee Grinder",
|
|
47
|
+
"summary": "Adjustable ceramic burr grinder",
|
|
48
|
+
"data": ["HMK-2278", "Coffee Grinder", "1", "£40.00", "£40.00"]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"caption": "Kitchen Scale",
|
|
52
|
+
"summary": "Digital scale, 5kg capacity",
|
|
53
|
+
"data": ["HMK-2321", "Kitchen Scale", "1", "£22.00", "£22.00"]
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"caption": "Office Supplies",
|
|
59
|
+
"summary": "Daily work essentials",
|
|
60
|
+
"data": [],
|
|
61
|
+
"sub": [
|
|
62
|
+
{
|
|
63
|
+
"caption": "A4 Notebook",
|
|
64
|
+
"summary": "200 pages, ruled",
|
|
65
|
+
"data": ["OFC-1003", "A4 Notebook", "3", "£4.00", "£12.00"]
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"caption": "Ballpoint Pen Set",
|
|
69
|
+
"summary": "Pack of 10 blue pens",
|
|
70
|
+
"data": ["OFC-1045", "Ballpoint Pen Set", "1", "£6.00", "£6.00"]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"caption": "Desk Organizer",
|
|
74
|
+
"summary": "Metal mesh, 5 compartments",
|
|
75
|
+
"data": ["OFC-1089", "Desk Organizer", "1", "£18.00", "£18.00"]
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"tax": "£34.80",
|
|
81
|
+
"discount": "£15.00",
|
|
82
|
+
"total": "£368.80",
|
|
83
|
+
"paid": "£250.00",
|
|
84
|
+
"remaining": "£118.80"
|
|
85
|
+
}
|
|
86
|
+
"></zn-order-table>
|
|
10
87
|
```
|
|
11
88
|
|
|
12
89
|
## Examples
|
|
13
90
|
|
|
14
|
-
###
|
|
91
|
+
### FirstExample
|
|
15
92
|
|
|
16
93
|
TODO
|
|
17
94
|
|
|
18
|
-
###
|
|
95
|
+
### SecondExample
|
|
19
96
|
|
|
20
97
|
TODO
|
|
21
98
|
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ import {FormControlController, validValidityState} from "../../internal/form";
|
|
|
4
4
|
import {HasSlotController} from '../../internal/slot';
|
|
5
5
|
import {html, literal} from 'lit/static-html.js';
|
|
6
6
|
import {ifDefined} from 'lit/directives/if-defined.js';
|
|
7
|
-
import {property, query} from 'lit/decorators.js';
|
|
7
|
+
import {property, query, queryAll} from 'lit/decorators.js';
|
|
8
8
|
import ZincElement from '../../internal/zinc-element';
|
|
9
9
|
import ZnDropdown from "../dropdown";
|
|
10
10
|
import ZnIcon from "../icon";
|
|
@@ -30,6 +30,7 @@ import styles from './button.scss';
|
|
|
30
30
|
* @slot - The button's label.
|
|
31
31
|
* @slot prefix - A presentational prefix icon or similar element.
|
|
32
32
|
* @slot suffix - A presentational suffix icon or similar element.
|
|
33
|
+
* @slot cancel - Slot for custom cancel button/content when autoClick is active.
|
|
33
34
|
*
|
|
34
35
|
* @csspart base - The component's base wrapper.
|
|
35
36
|
* @csspart prefix - The container that wraps the prefix.
|
|
@@ -47,8 +48,14 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
47
48
|
|
|
48
49
|
private readonly formControlController = new FormControlController(this);
|
|
49
50
|
private readonly hasSlotController = new HasSlotController(this, '[default]');
|
|
51
|
+
private _autoClickTimeout: number | undefined;
|
|
52
|
+
private _loadingState = {
|
|
53
|
+
countdown: null as number | null,
|
|
54
|
+
interval: undefined as number | undefined,
|
|
55
|
+
};
|
|
50
56
|
|
|
51
57
|
@query('.button') button: HTMLButtonElement;
|
|
58
|
+
@queryAll('.loading-countdown') countdownContainer: HTMLElement[];
|
|
52
59
|
|
|
53
60
|
@property({}) color: 'default' | 'secondary' | 'error' | 'info' | 'success' | 'warning' |
|
|
54
61
|
'transparent' | 'star' = 'default';
|
|
@@ -59,7 +66,6 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
59
66
|
@property({type: Boolean}) grow = false;
|
|
60
67
|
@property({type: Boolean}) square = false;
|
|
61
68
|
|
|
62
|
-
|
|
63
69
|
@property({attribute: 'dropdown-closer', type: Boolean}) dropdownCloser = false;
|
|
64
70
|
|
|
65
71
|
@property({type: Number}) notification: number;
|
|
@@ -94,6 +100,16 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
94
100
|
// Tooltip Specific
|
|
95
101
|
@property() tooltip: string;
|
|
96
102
|
|
|
103
|
+
// Auto Click Specific
|
|
104
|
+
@property({type: Boolean, attribute: 'auto-click'}) autoClick = false;
|
|
105
|
+
@property({type: Number, attribute: 'auto-click-delay'}) autoClickDelay = 2000;
|
|
106
|
+
@property({type: String, attribute: 'loading-text'}) loadingText = 'Loading...';
|
|
107
|
+
@property({
|
|
108
|
+
type: String,
|
|
109
|
+
attribute: 'loading-text-position'
|
|
110
|
+
}) loadingTextPosition: 'left' | 'right' | 'center' | string = 'center';
|
|
111
|
+
@property({type: Boolean}) loading = false;
|
|
112
|
+
|
|
97
113
|
get validity() {
|
|
98
114
|
if (this._isButton() && this.button) {
|
|
99
115
|
return (this.button as HTMLButtonElement).validity;
|
|
@@ -102,7 +118,6 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
102
118
|
return validValidityState;
|
|
103
119
|
}
|
|
104
120
|
|
|
105
|
-
|
|
106
121
|
get validationMessage() {
|
|
107
122
|
if (this._isButton() && this.button) {
|
|
108
123
|
return (this.button as HTMLButtonElement).validationMessage;
|
|
@@ -117,6 +132,47 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
117
132
|
}
|
|
118
133
|
}
|
|
119
134
|
|
|
135
|
+
disconnectedCallback() {
|
|
136
|
+
super.disconnectedCallback();
|
|
137
|
+
this.teardownAutoClick();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
protected updated(changedProps: Map<string, any>) {
|
|
141
|
+
super.updated(changedProps);
|
|
142
|
+
if (changedProps.has('autoClick')) {
|
|
143
|
+
if (this.autoClick) {
|
|
144
|
+
this.setupAutoClick();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (this.button) {
|
|
148
|
+
const oldOverlay = this.button.querySelector('.button--loading-fill');
|
|
149
|
+
if (oldOverlay) {
|
|
150
|
+
oldOverlay.remove();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (this.loading) {
|
|
154
|
+
// Add loading overlay
|
|
155
|
+
const duration = `${this.autoClickDelay / 1000}s`;
|
|
156
|
+
const overlay = document.createElement('div');
|
|
157
|
+
overlay.classList.add('button--loading-fill');
|
|
158
|
+
overlay.setAttribute('style', `--loading-duration: ${duration}`);
|
|
159
|
+
|
|
160
|
+
if (this.button.classList.contains('button--transparent')) {
|
|
161
|
+
overlay.classList.add('button--loading-fill-transparent');
|
|
162
|
+
this.button.classList.add('button--loading-bg-transparent');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this.button.prepend(overlay);
|
|
166
|
+
this.button.classList.add('button--loading-bg');
|
|
167
|
+
} else {
|
|
168
|
+
this.button.classList.remove('button--loading-bg');
|
|
169
|
+
this.button.classList.remove('button--loading-bg-transparent');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this.updateCountdownText();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
120
176
|
checkValidity() {
|
|
121
177
|
if (this._isButton() && this.button) {
|
|
122
178
|
return (this.button as HTMLButtonElement).checkValidity();
|
|
@@ -180,16 +236,82 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
180
236
|
return !this._isLink();
|
|
181
237
|
}
|
|
182
238
|
|
|
183
|
-
|
|
184
|
-
|
|
239
|
+
setupAutoClick() {
|
|
240
|
+
if (!this.button) return;
|
|
241
|
+
|
|
242
|
+
if (this._autoClickTimeout) {
|
|
243
|
+
window.clearTimeout(this._autoClickTimeout);
|
|
244
|
+
this._autoClickTimeout = undefined;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (this._loadingState.interval) {
|
|
248
|
+
window.clearInterval(this._loadingState.interval);
|
|
249
|
+
this._loadingState.interval = undefined;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
this.loading = true;
|
|
253
|
+
this._loadingState.countdown = Math.ceil(this.autoClickDelay / 1000);
|
|
254
|
+
this.updateCountdownText();
|
|
255
|
+
|
|
256
|
+
this._loadingState.interval = window.setInterval(() => {
|
|
257
|
+
if (this._loadingState.countdown && this._loadingState.countdown > 0) {
|
|
258
|
+
this._loadingState.countdown--;
|
|
259
|
+
this.updateCountdownText();
|
|
260
|
+
}
|
|
261
|
+
}, 1000);
|
|
262
|
+
|
|
263
|
+
this._autoClickTimeout = window.setTimeout(() => {
|
|
264
|
+
this.loading = false;
|
|
265
|
+
this._loadingState.countdown = null;
|
|
266
|
+
this.updateCountdownText();
|
|
267
|
+
|
|
268
|
+
if (this._loadingState.interval) {
|
|
269
|
+
window.clearInterval(this._loadingState.interval);
|
|
270
|
+
this._loadingState.interval = undefined;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
this.button?.click();
|
|
274
|
+
}, this.autoClickDelay);
|
|
275
|
+
}
|
|
185
276
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
277
|
+
updateCountdownText() {
|
|
278
|
+
const text = this._loadingState.countdown && this._loadingState.countdown > 0 ? ` (${this._loadingState.countdown}s)` : '';
|
|
279
|
+
if (this.countdownContainer) {
|
|
280
|
+
for (const container of this.countdownContainer) {
|
|
281
|
+
container.textContent = text;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
189
285
|
|
|
286
|
+
teardownAutoClick() {
|
|
287
|
+
if (this._autoClickTimeout) {
|
|
288
|
+
window.clearTimeout(this._autoClickTimeout);
|
|
289
|
+
this._autoClickTimeout = undefined;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (this._loadingState.interval) {
|
|
293
|
+
window.clearInterval(this._loadingState.interval);
|
|
294
|
+
this._loadingState.interval = undefined;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
this.loading = false;
|
|
298
|
+
this._loadingState.countdown = null;
|
|
299
|
+
|
|
300
|
+
if (this.button) {
|
|
301
|
+
this.button.style.width = '';
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
protected render(): unknown {
|
|
306
|
+
const isLink = this._isLink();
|
|
307
|
+
const showCancel = this.loading && this.autoClick;
|
|
308
|
+
const icon = this.icon && !this.loading ? html`
|
|
309
|
+
<zn-icon part="icon" src="${this.icon}" id="xy2" size="${this.iconSize ? this.iconSize : 16}"
|
|
310
|
+
color="${this.iconColor ? this.iconColor : null}"></zn-icon>`
|
|
311
|
+
: '';
|
|
190
312
|
const tag = isLink ? literal`a` : literal`button`;
|
|
191
313
|
|
|
192
|
-
|
|
314
|
+
const buttonContent = html`
|
|
193
315
|
<${tag}
|
|
194
316
|
part="base"
|
|
195
317
|
class="${classMap({
|
|
@@ -230,10 +352,46 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
230
352
|
data-notification="${ifDefined(this.notification)}"
|
|
231
353
|
@click="${this.handleClick}">
|
|
232
354
|
${this.iconPosition === 'left' ? icon : ''}
|
|
233
|
-
<slot part="label"
|
|
355
|
+
<slot part="label"
|
|
356
|
+
class="${classMap({
|
|
357
|
+
'button__label': true,
|
|
358
|
+
'button__label--hidden': this.loading
|
|
359
|
+
})}"
|
|
360
|
+
style="--loading-duration: ${this.autoClickDelay / 1000}s">
|
|
361
|
+
${this.content}
|
|
362
|
+
</slot>
|
|
234
363
|
${this.iconPosition === 'right' ? icon : ''}
|
|
364
|
+
${this.loading ? html`
|
|
365
|
+
<div class="button--loading-container">
|
|
366
|
+
<span
|
|
367
|
+
class=${classMap({
|
|
368
|
+
'button--loading-text-bottom': true,
|
|
369
|
+
'button--loading-text-bottom-transparent': this.color === 'transparent',
|
|
370
|
+
[`button--loading-text-bottom-${this.loadingTextPosition}`]: !!this.loadingTextPosition,
|
|
371
|
+
})}>
|
|
372
|
+
${this.loadingText}<span class="loading-countdown"></span>
|
|
373
|
+
</span>
|
|
374
|
+
<span
|
|
375
|
+
class=${classMap({
|
|
376
|
+
'button--loading-text-top': true,
|
|
377
|
+
'button--loading-text-top-transparent': this.color === 'transparent',
|
|
378
|
+
[`button--loading-text-top-${this.loadingTextPosition}`]: !!this.loadingTextPosition,
|
|
379
|
+
})}>
|
|
380
|
+
${this.loadingText}<span class="loading-countdown"></span>
|
|
381
|
+
</span>
|
|
382
|
+
</div>
|
|
383
|
+
` : null}
|
|
235
384
|
</${tag}>`;
|
|
236
385
|
|
|
386
|
+
let content = this.autoClick ? html`
|
|
387
|
+
<div class="button--relative-wrapper">
|
|
388
|
+
${buttonContent}
|
|
389
|
+
${showCancel ? html`
|
|
390
|
+
<slot name="cancel" @click="${this.teardownAutoClick}"></slot>
|
|
391
|
+
` : null}
|
|
392
|
+
</div>
|
|
393
|
+
` : buttonContent;
|
|
394
|
+
|
|
237
395
|
if (this.tooltip !== undefined) {
|
|
238
396
|
content = html`
|
|
239
397
|
<zn-tooltip placement="top" content="${this.tooltip}">
|