@iamproperty/components 3.7.9 → 3.9.0-beta-1
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/assets/css/components/accordion.css.map +1 -1
- package/assets/css/components/actionbar-global.css +1 -0
- package/assets/css/components/actionbar-global.css.map +1 -0
- package/assets/css/components/actionbar.css +1 -0
- package/assets/css/components/actionbar.css.map +1 -0
- package/assets/css/components/dialog.css +1 -1
- package/assets/css/components/dialog.css.map +1 -1
- package/assets/css/components/fileupload.css.map +1 -1
- package/assets/css/components/forms.css +1 -1
- package/assets/css/components/forms.css.map +1 -1
- package/assets/css/components/header.css +1 -1
- package/assets/css/components/header.css.map +1 -1
- package/assets/css/components/lists.css.map +1 -1
- package/assets/css/components/nav-global.css +1 -0
- package/assets/css/components/nav-global.css.map +1 -0
- package/assets/css/components/nav.css +1 -1
- package/assets/css/components/nav.css.map +1 -1
- package/assets/css/components/nav.docs.css +1 -0
- package/assets/css/components/nav.docs.css.map +1 -0
- package/assets/css/components/nav.old.css +1 -0
- package/assets/css/components/nav.old.css.map +1 -0
- package/assets/css/components/pagination.css.map +1 -1
- package/assets/css/components/property-searchbar.css +1 -1
- package/assets/css/components/property-searchbar.css.map +1 -1
- package/assets/css/components/table.css +1 -1
- package/assets/css/components/table.css.map +1 -1
- package/assets/css/core.min.css +1 -1
- package/assets/css/core.min.css.map +1 -1
- package/assets/css/style.min.css +1 -1
- package/assets/css/style.min.css.map +1 -1
- package/assets/js/components/accordion/accordion.component.min.js +1 -1
- package/assets/js/components/actionbar/actionbar.component.js +305 -0
- package/assets/js/components/actionbar/actionbar.component.min.js +53 -0
- package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -0
- package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
- package/assets/js/components/card/card.component.min.js +1 -1
- package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
- package/assets/js/components/header/header.component.min.js +2 -2
- package/assets/js/components/nav/nav.component.js +294 -0
- package/assets/js/components/nav/nav.component.min.js +51 -0
- package/assets/js/components/nav/nav.component.min.js.map +1 -0
- package/assets/js/components/notification/notification.component.min.js +1 -1
- package/assets/js/components/pagination/pagination.component.min.js +1 -1
- package/assets/js/components/table/table.component.js +33 -0
- package/assets/js/components/table/table.component.min.js +11 -10
- package/assets/js/components/table/table.component.min.js.map +1 -1
- package/assets/js/components/tabs/tabs.component.min.js +1 -1
- package/assets/js/dynamic.min.js +3 -3
- package/assets/js/dynamic.min.js.map +1 -1
- package/assets/js/modules/dialogs.js +18 -5
- package/assets/js/modules/table.js +22 -4
- package/assets/js/scripts.bundle.js +15 -14
- package/assets/js/scripts.bundle.js.map +1 -1
- package/assets/js/scripts.bundle.min.js +2 -2
- package/assets/js/scripts.bundle.min.js.map +1 -1
- package/assets/sass/_corefiles.scss +2 -0
- package/assets/sass/_functions/mixins.scss +25 -0
- package/assets/sass/_functions/variables.scss +5 -3
- package/assets/sass/components/actionbar-global.scss +89 -0
- package/assets/sass/components/actionbar.scss +254 -0
- package/assets/sass/components/dialog.scss +99 -1
- package/assets/sass/components/forms.scss +96 -21
- package/assets/sass/components/nav-global.scss +619 -0
- package/assets/sass/components/nav.docs.scss +54 -0
- package/assets/sass/components/nav.old.scss +965 -0
- package/assets/sass/components/nav.scss +450 -782
- package/assets/sass/components/table.scss +9 -1
- package/assets/sass/foundations/buttons.scss +87 -14
- package/assets/sass/foundations/links.scss +1 -1
- package/assets/sass/foundations/reboot.scss +5 -3
- package/assets/ts/components/actionbar/README.md +55 -0
- package/assets/ts/components/actionbar/actionbar.component.ts +396 -0
- package/assets/ts/components/nav/README.md +68 -0
- package/assets/ts/components/nav/nav.component.ts +370 -0
- package/assets/ts/components/table/table.component.ts +65 -0
- package/assets/ts/modules/dialogs.ts +24 -6
- package/assets/ts/modules/table.ts +29 -7
- package/dist/components.es.js +1013 -1258
- package/dist/components.umd.js +97 -47
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Actionbar/Actionbar.vue +20 -0
- package/src/components/Actionbar/README.md +40 -0
- package/src/components/Nav/Nav.vue +20 -195
- package/src/components/Nav/README.md +43 -13
- package/src/components/Nav-old/Nav.vue +213 -0
- package/src/components/Nav-old/README.md +23 -0
- package/src/components/Nav/Nav.spec.js +0 -35
|
@@ -121,7 +121,7 @@ table.border-0 {
|
|
|
121
121
|
--wrapper-padding: #{rem(32)};
|
|
122
122
|
--bg-colour: #ffffff;
|
|
123
123
|
display: block;
|
|
124
|
-
background:
|
|
124
|
+
background: white;
|
|
125
125
|
padding: var(--wrapper-padding);
|
|
126
126
|
box-shadow: 0px 6px 12px rgba(0,0,0,0.11);
|
|
127
127
|
border-radius: rem(8);
|
|
@@ -134,10 +134,17 @@ table.border-0 {
|
|
|
134
134
|
|
|
135
135
|
table {
|
|
136
136
|
margin-bottom: 0;
|
|
137
|
+
|
|
138
|
+
td:has(input[type="checkbox"]) {
|
|
139
|
+
width: rem(30);
|
|
140
|
+
min-width: rem(30);
|
|
141
|
+
max-width: rem(30);
|
|
142
|
+
}
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
@media (forced-colors: active) {
|
|
140
146
|
--wrapper-padding: 0;
|
|
147
|
+
background: var(--colour-canvas-2);
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
150
|
|
|
@@ -162,6 +169,7 @@ table.border-0 {
|
|
|
162
169
|
margin-left: -1.5rem;
|
|
163
170
|
margin-right: -1.5rem;
|
|
164
171
|
margin-bottom: 0;
|
|
172
|
+
background: white;
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
.btn {
|
|
5
5
|
|
|
6
6
|
--btn-margin: #{rem(16)};
|
|
7
|
+
--btn-padding-block: #{rem(12)};
|
|
8
|
+
--btn-padding-inline: #{rem(40)};
|
|
9
|
+
--btn-border-width: 2px;
|
|
7
10
|
|
|
8
11
|
@include media-breakpoint-up(sm) {
|
|
9
12
|
|
|
@@ -29,12 +32,12 @@
|
|
|
29
32
|
user-select: none;
|
|
30
33
|
|
|
31
34
|
background: var(--colour-btn-bg);
|
|
32
|
-
border:
|
|
35
|
+
border: var(--btn-border-width) solid var(--colour-btn-border);
|
|
33
36
|
color: var(--colour-btn);
|
|
34
37
|
|
|
35
38
|
font-size: rem(18);
|
|
36
39
|
line-height: rem(24);
|
|
37
|
-
padding: calc(
|
|
40
|
+
padding: calc(var(--btn-padding-block) - var(--btn-border-width)) calc(var(--btn-padding-inline) - var(--btn-border-width));
|
|
38
41
|
border-radius: rem(24);
|
|
39
42
|
margin-bottom: var(--btn-margin);
|
|
40
43
|
|
|
@@ -90,20 +93,59 @@ a:is(:hover, :focus, .hover, :active, .active):not([disabled]) .btn-secondary,
|
|
|
90
93
|
}
|
|
91
94
|
// #endregion
|
|
92
95
|
|
|
96
|
+
// #region Action button
|
|
97
|
+
.btn-action {
|
|
98
|
+
|
|
99
|
+
--btn-border-width: 1px;
|
|
100
|
+
--btn-padding-block: #{rem(6)};
|
|
101
|
+
--btn-padding-inline: #{rem(6)};
|
|
102
|
+
|
|
103
|
+
background-color: var(--colour-canvas-2);
|
|
104
|
+
border: var(--btn-border-width) solid var(--colour-muted);
|
|
105
|
+
border-radius: rem(4)!important;
|
|
106
|
+
font-weight: 400!important;
|
|
107
|
+
font-size: 1rem;
|
|
108
|
+
line-height: rem(20);
|
|
109
|
+
|
|
110
|
+
color: var(--colour-heading);
|
|
111
|
+
|
|
112
|
+
&.btn[class*=fa-]:before {
|
|
113
|
+
margin-right: rem(6);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
a:is(:hover, :focus, .hover, :focus-within):not([disabled],:active, .active) &,
|
|
118
|
+
&:is(:hover, :focus, .hover, :focus-within):not([disabled],:active, .active) {
|
|
119
|
+
background: var(--colour-btn-action-hover-bg);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
a:is(:active, .active):not([disabled]) &,
|
|
124
|
+
&:is(:active, .active):not([disabled]) {
|
|
125
|
+
|
|
126
|
+
filter: brightness(85%);
|
|
127
|
+
transition: background .1s, color .1s;
|
|
128
|
+
color: var(--colour-heading);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// #endregion
|
|
132
|
+
|
|
93
133
|
// #region button with icon
|
|
94
134
|
.btn {
|
|
95
135
|
&[class*="fa-"]:before {
|
|
96
136
|
|
|
97
137
|
font-family: "Font Awesome 6 Pro";
|
|
98
138
|
margin-right: 1rem;
|
|
139
|
+
line-height: 1em;
|
|
99
140
|
}
|
|
100
141
|
|
|
101
|
-
[class*="fa-"]{
|
|
142
|
+
i[class*="fa-"]{
|
|
102
143
|
|
|
103
144
|
font-family: "Font Awesome 6 Pro";
|
|
104
145
|
margin-right: 1rem;
|
|
105
|
-
|
|
146
|
+
line-height: 1em;
|
|
106
147
|
font-style: inherit;
|
|
148
|
+
|
|
107
149
|
&:not(:first-child){
|
|
108
150
|
margin-left: 1rem;
|
|
109
151
|
margin-right: 0;
|
|
@@ -146,22 +188,34 @@ a:is(:hover, :focus, .hover, :active, .active):not([disabled]) .btn-secondary,
|
|
|
146
188
|
// #region button small and tag
|
|
147
189
|
.btn.btn-sm {
|
|
148
190
|
|
|
149
|
-
padding:
|
|
191
|
+
--btn-padding-block: #{rem(8)};
|
|
192
|
+
--btn-padding-inline: #{rem(32)};
|
|
150
193
|
}
|
|
151
194
|
// #endregion
|
|
152
195
|
|
|
153
196
|
// #region btn compact
|
|
154
197
|
.btn-compact {
|
|
155
|
-
padding: calc(rem(12) - 2px)!important;
|
|
156
|
-
margin-bottom: rem(8)!important;
|
|
157
|
-
margin-right: rem(8)!important;
|
|
158
198
|
|
|
199
|
+
--compact-size: #{rem(48)};
|
|
200
|
+
|
|
201
|
+
padding: 0!important;
|
|
202
|
+
margin-bottom: rem(8)!important;
|
|
203
|
+
|
|
204
|
+
&:not(:last-child){
|
|
205
|
+
margin-right: rem(8);
|
|
206
|
+
}
|
|
159
207
|
text-align: center;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
208
|
+
|
|
209
|
+
width: calc(var(--compact-size));
|
|
210
|
+
min-width: calc(var(--compact-size));
|
|
211
|
+
max-width: calc(var(--compact-size));
|
|
212
|
+
height: calc(var(--compact-size))!important;
|
|
213
|
+
min-height: calc(var(--compact-size))!important;
|
|
214
|
+
max-height: calc(var(--compact-size))!important;
|
|
215
|
+
|
|
216
|
+
line-height: calc(var(--compact-size) - var(--btn-border-width) - var(--btn-border-width))!important;
|
|
217
|
+
|
|
218
|
+
text-indent: -500px;
|
|
165
219
|
overflow: hidden;
|
|
166
220
|
position: relative;
|
|
167
221
|
font-size: rem(20);
|
|
@@ -173,10 +227,29 @@ a:is(:hover, :focus, .hover, :active, .active):not([disabled]) .btn-secondary,
|
|
|
173
227
|
width: 100%;
|
|
174
228
|
height: 100%;
|
|
175
229
|
text-indent: 0;
|
|
176
|
-
line-height: calc(
|
|
230
|
+
line-height: calc(var(--compact-size) - var(--btn-border-width) - var(--btn-border-width))!important;
|
|
177
231
|
font-weight: 900;
|
|
178
232
|
}
|
|
179
233
|
|
|
234
|
+
&.btn-sm {
|
|
235
|
+
|
|
236
|
+
--compact-size: #{rem(40)};
|
|
237
|
+
|
|
238
|
+
font-size: 1rem;
|
|
239
|
+
padding: 0!important;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
&.btn-action {
|
|
243
|
+
|
|
244
|
+
--compact-size: #{rem(32)};
|
|
245
|
+
font-size: 1rem;
|
|
246
|
+
|
|
247
|
+
&:before {
|
|
248
|
+
font-size: 1em;
|
|
249
|
+
font-weight: 400;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
180
253
|
&.btn-secondary {
|
|
181
254
|
|
|
182
255
|
--colour-btn-border: transparent;
|
|
@@ -51,7 +51,6 @@ body {
|
|
|
51
51
|
width: 100%;
|
|
52
52
|
line-height: 1.2;
|
|
53
53
|
min-height: 100%;
|
|
54
|
-
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
// #region scrollbars
|
|
@@ -142,7 +141,7 @@ details {
|
|
|
142
141
|
|
|
143
142
|
|
|
144
143
|
// #region Undefined web components
|
|
145
|
-
:is(*):not(:defined) {
|
|
144
|
+
:is(*):not(:defined):not(iam-nav) {
|
|
146
145
|
display: block;
|
|
147
146
|
padding: rem(24);
|
|
148
147
|
margin-bottom: rem(24);
|
|
@@ -178,9 +177,12 @@ main > :is(*):not(:defined) {
|
|
|
178
177
|
|
|
179
178
|
main {
|
|
180
179
|
position: relative;
|
|
180
|
+
|
|
181
|
+
> *:first-child {
|
|
182
|
+
padding-top: 2rem;
|
|
183
|
+
}
|
|
181
184
|
}
|
|
182
185
|
|
|
183
|
-
|
|
184
186
|
.container.notification__holder {
|
|
185
187
|
|
|
186
188
|
position: fixed;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
**Add the below to your initialise script**
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
import('../node_modules/@iamproperty/components/assets/js/components/actionbar/actionbar.component.min').then(module => { // Might need to update the path
|
|
5
|
+
|
|
6
|
+
if (!window.customElements.get(`iam-actionbar`))
|
|
7
|
+
window.customElements.define(`iam-actionbar`, module.default);
|
|
8
|
+
|
|
9
|
+
}).catch((err) => {
|
|
10
|
+
console.log(err.message);
|
|
11
|
+
});
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Add the below HTML code to where you want the component to live.**
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
<iam-actionbar data-selectall data-search>
|
|
18
|
+
|
|
19
|
+
<div class="dialog__wrapper">
|
|
20
|
+
<button class="btn btn-action mb-0 me-0">Quick filter</button>
|
|
21
|
+
<dialog class="dialog--list">
|
|
22
|
+
<div class="pb-0">
|
|
23
|
+
<input type="radio" name="sorta" data-sort="" id="follow-up-oldesta" value="follow-up-oldest">
|
|
24
|
+
<label for="follow-up-oldesta" class="radio--tick">Option 1</label>
|
|
25
|
+
|
|
26
|
+
<input type="radio" name="sorta" data-sort="" id="follow-up-newesta" value="follow-up-newest">
|
|
27
|
+
<label for="follow-up-newesta" class="radio--tick">Option 2</label>
|
|
28
|
+
|
|
29
|
+
<input type="radio" name="sorta" data-sort="" id="date-instructed-oldesta" value="date-instructed-oldest" checked="" autofocus="true">
|
|
30
|
+
<label for="date-instructed-oldesta" class="radio--tick">Option 3</label>
|
|
31
|
+
|
|
32
|
+
<input type="radio" name="sorta" data-sort="" id="date-instructed-newesta" value="date-instructed-newest">
|
|
33
|
+
<label for="date-instructed-newesta" class="radio--tick mb-0">Option 4</label>
|
|
34
|
+
</div>
|
|
35
|
+
</dialog>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<button class="btn btn-primary btn-sm fa-plus" id="uploadBtn">Upload document</button>
|
|
39
|
+
|
|
40
|
+
<button class="btn btn-action fa-pen-to-square" data-single slot="selected">Edit</button>
|
|
41
|
+
<button class="btn btn-action fa-box-archive" slot="selected">Archive</button>
|
|
42
|
+
<button class="btn btn-action fa-trash-can" slot="selected">Delete</button>
|
|
43
|
+
<hr slot="selected" />
|
|
44
|
+
<button class="btn btn-action" slot="selected">Cancel</button>
|
|
45
|
+
|
|
46
|
+
</iam-actionbar>
|
|
47
|
+
```
|
|
48
|
+
**Properties**
|
|
49
|
+
|
|
50
|
+
| Option | Type | Default Value | Description |
|
|
51
|
+
| ------ | ---- | ------------- | ----------- |
|
|
52
|
+
| data-selectall | - | - | Optional flag to include the select all button |
|
|
53
|
+
| data-search | - | - | Optional flag to include the search button and functionality |
|
|
54
|
+
| data-switchviews | - | - | Optional flag to include the switch views buttons |
|
|
55
|
+
| data-view | String | square | Required if you have the above flag set. Can be set to wither 'square','list' or 'small'. |
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import extendDialogs from "../../modules/dialogs";
|
|
3
|
+
|
|
4
|
+
// Data layer Web component created
|
|
5
|
+
window.dataLayer = window.dataLayer || [];
|
|
6
|
+
window.dataLayer.push({
|
|
7
|
+
"event": "customElementRegistered",
|
|
8
|
+
"element": "action bar"
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
function setSelectAllInput(element, value){
|
|
12
|
+
|
|
13
|
+
if(element && value == "all"){
|
|
14
|
+
|
|
15
|
+
element.querySelector('input').indeterminate = false;
|
|
16
|
+
element.querySelector('input').checked = true;
|
|
17
|
+
element.querySelector('label').textContent = `Select all`;
|
|
18
|
+
}
|
|
19
|
+
else if(element && value == 0){
|
|
20
|
+
|
|
21
|
+
element.querySelector('input').indeterminate = false;
|
|
22
|
+
element.querySelector('input').checked = false;
|
|
23
|
+
element.querySelector('label').textContent = `Select all`;
|
|
24
|
+
}
|
|
25
|
+
else if(element && value){
|
|
26
|
+
|
|
27
|
+
element.querySelector('input').indeterminate = true;
|
|
28
|
+
element.querySelector('input').checked = false;
|
|
29
|
+
element.querySelector('label').textContent = `${value} item${value > 1 ? 's' : ''} selected`;
|
|
30
|
+
}
|
|
31
|
+
else if(element){
|
|
32
|
+
|
|
33
|
+
element.querySelector('input').checked = false;
|
|
34
|
+
element.querySelector('input').indeterminate = false;
|
|
35
|
+
element.querySelector('label').textContent = `Select all`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class iamActionbar extends HTMLElement {
|
|
40
|
+
|
|
41
|
+
constructor(){
|
|
42
|
+
super();
|
|
43
|
+
this.attachShadow({ mode: 'open'});
|
|
44
|
+
|
|
45
|
+
const assetLocation = document.body.hasAttribute('data-assets-location') ? document.body.getAttribute('data-assets-location') : '/assets'
|
|
46
|
+
const coreCSS = document.body.hasAttribute('data-core-css') ? document.body.getAttribute('data-core-css') : `${assetLocation}/css/core.min.css`;
|
|
47
|
+
const loadCSS = `@import "${assetLocation}/css/components/actionbar.css";`;
|
|
48
|
+
|
|
49
|
+
const template = document.createElement('template');
|
|
50
|
+
template.innerHTML = `
|
|
51
|
+
<style>
|
|
52
|
+
@import "${coreCSS}";
|
|
53
|
+
${loadCSS}
|
|
54
|
+
${this.hasAttribute('css') ? `@import "${this.getAttribute('css')}";` : ``}
|
|
55
|
+
</style>
|
|
56
|
+
<link rel="stylesheet" href="https://kit.fontawesome.com/26fdbf0179.css" crossorigin="anonymous">
|
|
57
|
+
<div class="actionbar__wrapper">
|
|
58
|
+
<div class="actionbar">
|
|
59
|
+
<div class="safe-area">
|
|
60
|
+
<slot></slot>
|
|
61
|
+
<div class="body">
|
|
62
|
+
<div class="dialog__wrapper dialog__wrapper--right dialog-overflow d-none show">
|
|
63
|
+
<button class="btn btn-secondary btn-compact fa-ellipsis-vertical m-0">More actions</button>
|
|
64
|
+
<dialog class="dialog--list">
|
|
65
|
+
<slot name="overflow"></slot>
|
|
66
|
+
<slot name="menu"></slot>
|
|
67
|
+
</dialog>
|
|
68
|
+
</div>
|
|
69
|
+
<button class="btn btn-secondary btn-compact btn-sm fa-search m-0" data-search="">Search</button>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
<div class="actionbar--selected">
|
|
74
|
+
<div class="safe-area">
|
|
75
|
+
<slot name="selected"></slot>
|
|
76
|
+
<div class="body">
|
|
77
|
+
<div class="dialog__wrapper dialog__wrapper--right dialog-overflow d-none show">
|
|
78
|
+
<button class="btn btn-secondary btn-compact fa-ellipsis-vertical m-0">More actions</button>
|
|
79
|
+
<dialog class="dialog--list">
|
|
80
|
+
<slot name="selected-overflow"></slot>
|
|
81
|
+
</dialog>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="actionbar--search">
|
|
87
|
+
<button data-search class="btn btn-compact fa-xmark-large btn-secondary m-0" >Close</button>
|
|
88
|
+
|
|
89
|
+
<div class="search-wrapper">
|
|
90
|
+
<label for="search" class="visually-hidden">Input field label</label>
|
|
91
|
+
<button class="suffix"><i class="fa-regular fa-search"></i></button>
|
|
92
|
+
<input type="text" id="search" name="search" required="">
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
`;
|
|
98
|
+
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
connectedCallback() {
|
|
102
|
+
|
|
103
|
+
let that = this;
|
|
104
|
+
const actionbarWrapper = this.shadowRoot.querySelector('.actionbar__wrapper');
|
|
105
|
+
|
|
106
|
+
// #region select all
|
|
107
|
+
if(this.hasAttribute('data-selectall')){
|
|
108
|
+
|
|
109
|
+
actionbarWrapper.insertAdjacentHTML( 'afterbegin', `<div class="selectall pb-0"><input type="checkbox" name="selectall" id="selectall"><label for="selectall" class="m-0">Select all</label></div>` );
|
|
110
|
+
let selectAll = this.shadowRoot.querySelector('.selectall');
|
|
111
|
+
|
|
112
|
+
if(this.hasAttribute('data-selected')){
|
|
113
|
+
setSelectAllInput(selectAll, this.getAttribute('data-selected'));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
selectAll.addEventListener('change', (event) => {
|
|
117
|
+
|
|
118
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('input')){
|
|
119
|
+
|
|
120
|
+
if(event.target.closest('input').checked)
|
|
121
|
+
this.setAttribute('data-selected','all');
|
|
122
|
+
else
|
|
123
|
+
this.setAttribute('data-selected',0);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
let cancelButton = this.querySelector('button[data-cancel]');
|
|
128
|
+
if(cancelButton){
|
|
129
|
+
cancelButton.addEventListener('click', (event) => {
|
|
130
|
+
|
|
131
|
+
this.setAttribute('data-selected',0);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// #endregion
|
|
136
|
+
|
|
137
|
+
// #region switchviews
|
|
138
|
+
if(this.hasAttribute('data-switchviews')){
|
|
139
|
+
|
|
140
|
+
let btns = '';
|
|
141
|
+
let viewList = this.getAttribute('data-switchviews').split(',');
|
|
142
|
+
|
|
143
|
+
viewList.forEach((view,index) => {
|
|
144
|
+
|
|
145
|
+
let icon = 'fa-grid-2';
|
|
146
|
+
|
|
147
|
+
if(view == "list")
|
|
148
|
+
icon = 'fa-grip-lines';
|
|
149
|
+
else if(view == "small")
|
|
150
|
+
icon = 'fa-bars';
|
|
151
|
+
|
|
152
|
+
btns += `<button class="btn btn-action btn-compact mb-0 fa-regular ${icon}">${view}</button>`;
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
actionbarWrapper.insertAdjacentHTML( 'afterbegin', `<div class="views m-0">${btns}</div>` );
|
|
156
|
+
let views = this.shadowRoot.querySelector('.views');
|
|
157
|
+
|
|
158
|
+
views.addEventListener('click', (event) => {
|
|
159
|
+
|
|
160
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('.btn-action')){
|
|
161
|
+
|
|
162
|
+
let btn = event.target.closest('.btn-action');
|
|
163
|
+
|
|
164
|
+
this.setAttribute('data-view',btn.textContent);
|
|
165
|
+
|
|
166
|
+
const switchEvent = new CustomEvent("switch-view", { detail: { view: btn.textContent} });
|
|
167
|
+
this.dispatchEvent(switchEvent);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// #endregion
|
|
172
|
+
|
|
173
|
+
// #region search
|
|
174
|
+
const searchBar = this.shadowRoot.querySelector('.actionbar--search');
|
|
175
|
+
|
|
176
|
+
if(this.hasAttribute('data-search') && this.getAttribute('data-search') == 'show')
|
|
177
|
+
searchBar.classList.add('show');
|
|
178
|
+
|
|
179
|
+
this.shadowRoot.addEventListener('click', (event) => {
|
|
180
|
+
|
|
181
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('button[data-search]')){
|
|
182
|
+
searchBar.classList.toggle('show');
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
searchBar.addEventListener('keyup', (event) => {
|
|
187
|
+
|
|
188
|
+
const keyupEvent = new CustomEvent("search-keyup", { detail: { search: searchBar.querySelector('input').value } });
|
|
189
|
+
this.dispatchEvent(keyupEvent);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
searchBar.addEventListener('change', (event) => {
|
|
193
|
+
|
|
194
|
+
const changeEvent = new CustomEvent("search-change", { detail: { search: searchBar.querySelector('input').value } });
|
|
195
|
+
this.dispatchEvent(changeEvent);
|
|
196
|
+
});
|
|
197
|
+
searchBar.addEventListener('click', (event) => {
|
|
198
|
+
|
|
199
|
+
if (event && event.target instanceof HTMLElement && event.target.closest('button.suffix')){
|
|
200
|
+
|
|
201
|
+
const submitEvent = new CustomEvent("search-submit", { detail: { search: searchBar.querySelector('input').value } });
|
|
202
|
+
this.dispatchEvent(submitEvent);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
// #endregion
|
|
206
|
+
|
|
207
|
+
// Make sure dialogs created in the shadow dom work
|
|
208
|
+
Array.from(this.shadowRoot.querySelectorAll('.body')).forEach((element,index) => {
|
|
209
|
+
|
|
210
|
+
extendDialogs(element);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// #region Reponsive safe area
|
|
214
|
+
function hideButtons () {
|
|
215
|
+
|
|
216
|
+
const wrapperWidth = actionbarWrapper.scrollWidth;
|
|
217
|
+
const screenWidth = document.documentElement.scrollWidth;
|
|
218
|
+
let safeAreaWidth = 750;
|
|
219
|
+
let elementMargin = 16;
|
|
220
|
+
let mobileSafeWidth = that.hasAttribute('data-switchviews') ? 144 : 210;
|
|
221
|
+
|
|
222
|
+
// We need to modify the widths to mimic the CSS's scaling functionality
|
|
223
|
+
let modifier = 1;
|
|
224
|
+
if (screenWidth >= 992 && screenWidth <= 1280){
|
|
225
|
+
modifier = screenWidth/1280;
|
|
226
|
+
}
|
|
227
|
+
else if (screenWidth >= 576 && screenWidth <= 1280) {
|
|
228
|
+
modifier = screenWidth/768;
|
|
229
|
+
}
|
|
230
|
+
else if (screenWidth < 576) {
|
|
231
|
+
modifier = screenWidth/375;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Work out the safe sapce width depending upon the wrappers width and modifier
|
|
235
|
+
if (wrapperWidth >= 992 && wrapperWidth <= 1280){
|
|
236
|
+
safeAreaWidth = safeAreaWidth*modifier;
|
|
237
|
+
}
|
|
238
|
+
else if (wrapperWidth >= 576 && wrapperWidth <= 1280) {
|
|
239
|
+
safeAreaWidth = 450*modifier;
|
|
240
|
+
}
|
|
241
|
+
else if (wrapperWidth < 576) {
|
|
242
|
+
safeAreaWidth = mobileSafeWidth*modifier;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Margin in between elements
|
|
246
|
+
elementMargin = elementMargin*modifier;
|
|
247
|
+
|
|
248
|
+
// If the wrapper width is small we want to reduce the btn sizes by adding or removing btn-compact classes
|
|
249
|
+
if (wrapperWidth < 576) {
|
|
250
|
+
|
|
251
|
+
Array.from(that.querySelectorAll(':scope > .btn:not(.js-updated)')).forEach((element,index) => {
|
|
252
|
+
|
|
253
|
+
element.className = element.className.replace(' btn-compact',' _btn-compact');
|
|
254
|
+
element.classList.add('btn-compact');
|
|
255
|
+
element.classList.add('js-updated');
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
|
|
260
|
+
Array.from(that.querySelectorAll(':scope > .btn.js-updated')).forEach((element,index) => {
|
|
261
|
+
|
|
262
|
+
element.classList.remove('btn-compact');
|
|
263
|
+
element.classList.remove('js-updated');
|
|
264
|
+
element.className = element.className.replace(' _btn-compact',' btn-compact');
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Reset the elements before we decide what elements become slotted into the overflow
|
|
269
|
+
Array.from(that.querySelectorAll('[slot]')).forEach((element,index) => {
|
|
270
|
+
|
|
271
|
+
if(element.getAttribute("slot") == "overflow")
|
|
272
|
+
element.removeAttribute('slot');
|
|
273
|
+
|
|
274
|
+
if(element.getAttribute("slot") == "selected-overflow")
|
|
275
|
+
element.setAttribute('slot','selected');
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
Array.from(that.querySelectorAll('.show')).forEach((element,index) => {
|
|
279
|
+
|
|
280
|
+
element.classList.remove('show');
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
// Foreach safe area lets check what elements are slotted in them and if they need an overflow
|
|
284
|
+
Array.from(that.shadowRoot.querySelectorAll('.safe-area')).forEach((element,index) => {
|
|
285
|
+
|
|
286
|
+
// Decide on which overflow slot to use
|
|
287
|
+
let overflowSlot = "overflow"
|
|
288
|
+
|
|
289
|
+
if(element.querySelector('slot').hasAttribute('name') && element.querySelector('slot').getAttribute('name') == "selected")
|
|
290
|
+
overflowSlot = "selected-overflow";
|
|
291
|
+
|
|
292
|
+
// Get the slotted elements, remember they aren't children of the safe area
|
|
293
|
+
let elements = element.querySelector('slot').assignedElements();
|
|
294
|
+
let tempWidth = 44*modifier; // Allow space for the overflow button
|
|
295
|
+
|
|
296
|
+
// If search then allow for the search button width
|
|
297
|
+
if(that.hasAttribute('data-search'))
|
|
298
|
+
tempWidth += 44*modifier;
|
|
299
|
+
|
|
300
|
+
// Foreach element that isn't an action button or dialog wrapper add to the width, these will not be moved into the overflow slot
|
|
301
|
+
for (let i = 0; i < elements.length; i++) {
|
|
302
|
+
|
|
303
|
+
if(!elements[i].classList.contains('btn-action') && !elements[i].classList.contains('dialog__wrapper')){
|
|
304
|
+
|
|
305
|
+
tempWidth += elements[i].offsetWidth;
|
|
306
|
+
tempWidth += elementMargin;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Foreach dialog wrapper decide if safe in safe area or move into the overflow slot, dialog wrappers have priority over the action buttons
|
|
311
|
+
for (let i = 0; i < elements.length; i++) {
|
|
312
|
+
|
|
313
|
+
if(elements[i].classList.contains('dialog__wrapper')){
|
|
314
|
+
|
|
315
|
+
elements[i].classList.add('show');
|
|
316
|
+
tempWidth += elements[i].offsetWidth;
|
|
317
|
+
tempWidth += (elementMargin/2);
|
|
318
|
+
|
|
319
|
+
// If we have exceeded the safe area then lets break the loop
|
|
320
|
+
if(tempWidth - (elementMargin/2) > safeAreaWidth){
|
|
321
|
+
|
|
322
|
+
elements[i].classList.remove('show');
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Foreach action button
|
|
329
|
+
for (let i = 0; i < elements.length; i++) {
|
|
330
|
+
|
|
331
|
+
if(elements[i].classList.contains('btn-action')){
|
|
332
|
+
|
|
333
|
+
elements[i].classList.add('show');
|
|
334
|
+
tempWidth += elements[i].offsetWidth;
|
|
335
|
+
tempWidth += (elementMargin/2);
|
|
336
|
+
|
|
337
|
+
// If we have exceeded the safe area then lets break the loop
|
|
338
|
+
if(tempWidth - (elementMargin/2) > safeAreaWidth){
|
|
339
|
+
|
|
340
|
+
elements[i].classList.remove('show');
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
let overflowDialog = element.querySelector('.dialog-overflow');
|
|
347
|
+
|
|
348
|
+
if(overflowDialog)
|
|
349
|
+
overflowDialog.classList.add('d-none');
|
|
350
|
+
|
|
351
|
+
// Decide which elements go into the overflow slot
|
|
352
|
+
for (let i = 0; i < elements.length; i++) {
|
|
353
|
+
|
|
354
|
+
if(elements[i].classList.contains('btn-action') || elements[i].classList.contains('dialog__wrapper')){
|
|
355
|
+
if (!elements[i].classList.contains('show')){
|
|
356
|
+
|
|
357
|
+
// Move to the slot by changing the attribute
|
|
358
|
+
elements[i].setAttribute('slot',overflowSlot);
|
|
359
|
+
|
|
360
|
+
// if an element has been added to overflow slot then make sure we show the overflow menu button
|
|
361
|
+
if(overflowDialog)
|
|
362
|
+
overflowDialog.classList.remove('d-none');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Check buttons on load and when the wrapper element gets resized.
|
|
370
|
+
hideButtons();
|
|
371
|
+
new ResizeObserver(hideButtons).observe(actionbarWrapper);
|
|
372
|
+
// #endregion
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
static get observedAttributes() {
|
|
376
|
+
return ["data-selected"];
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
attributeChangedCallback(attrName, oldVal, newVal) {
|
|
380
|
+
|
|
381
|
+
switch (attrName) {
|
|
382
|
+
case "data-selected": {
|
|
383
|
+
|
|
384
|
+
let selectAll = this.shadowRoot.querySelector('.selectall');
|
|
385
|
+
|
|
386
|
+
if(selectAll)
|
|
387
|
+
setSelectAllInput(selectAll, newVal);
|
|
388
|
+
const event = new CustomEvent("selected", { detail: { selected: newVal } });
|
|
389
|
+
this.dispatchEvent(event);
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export default iamActionbar;
|