@iamproperty/components 3.8.0 → 4.0.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.
Files changed (99) hide show
  1. package/assets/css/components/actionbar-global.css +1 -0
  2. package/assets/css/components/actionbar-global.css.map +1 -0
  3. package/assets/css/components/actionbar.css +1 -0
  4. package/assets/css/components/actionbar.css.map +1 -0
  5. package/assets/css/components/collapsible-side.css +1 -0
  6. package/assets/css/components/collapsible-side.css.map +1 -0
  7. package/assets/css/components/dialog.css +1 -1
  8. package/assets/css/components/dialog.css.map +1 -1
  9. package/assets/css/components/forms.css +1 -1
  10. package/assets/css/components/forms.css.map +1 -1
  11. package/assets/css/components/header.css +1 -1
  12. package/assets/css/components/header.css.map +1 -1
  13. package/assets/css/components/lists.css.map +1 -1
  14. package/assets/css/components/nav-global.css +1 -0
  15. package/assets/css/components/nav-global.css.map +1 -0
  16. package/assets/css/components/nav.css +1 -1
  17. package/assets/css/components/nav.css.map +1 -1
  18. package/assets/css/components/nav.docs.css +1 -0
  19. package/assets/css/components/nav.docs.css.map +1 -0
  20. package/assets/css/components/nav.old.css +1 -0
  21. package/assets/css/components/nav.old.css.map +1 -0
  22. package/assets/css/components/pagination.css.map +1 -1
  23. package/assets/css/components/property-searchbar.css +1 -1
  24. package/assets/css/components/property-searchbar.css.map +1 -1
  25. package/assets/css/components/table.css +1 -1
  26. package/assets/css/components/table.css.map +1 -1
  27. package/assets/css/core.min.css +1 -1
  28. package/assets/css/core.min.css.map +1 -1
  29. package/assets/css/style.min.css +1 -1
  30. package/assets/css/style.min.css.map +1 -1
  31. package/assets/js/components/accordion/accordion.component.min.js +2 -2
  32. package/assets/js/components/actionbar/actionbar.component.js +305 -0
  33. package/assets/js/components/actionbar/actionbar.component.min.js +53 -0
  34. package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -0
  35. package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
  36. package/assets/js/components/card/card.component.min.js +1 -1
  37. package/assets/js/components/collapsible-side/collapsible-side.component.js +96 -0
  38. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +27 -0
  39. package/assets/js/components/collapsible-side/collapsible-side.component.min.js.map +1 -0
  40. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  41. package/assets/js/components/header/header.component.min.js +2 -2
  42. package/assets/js/components/nav/nav.component.js +294 -0
  43. package/assets/js/components/nav/nav.component.min.js +51 -0
  44. package/assets/js/components/nav/nav.component.min.js.map +1 -0
  45. package/assets/js/components/notification/notification.component.min.js +1 -1
  46. package/assets/js/components/pagination/pagination.component.min.js +1 -1
  47. package/assets/js/components/table/table.component.js +33 -0
  48. package/assets/js/components/table/table.component.min.js +12 -11
  49. package/assets/js/components/table/table.component.min.js.map +1 -1
  50. package/assets/js/components/tabs/tabs.component.min.js +1 -1
  51. package/assets/js/dynamic.min.js +3 -3
  52. package/assets/js/dynamic.min.js.map +1 -1
  53. package/assets/js/modules/dialogs.js +3 -0
  54. package/assets/js/modules/helpers.js +0 -13
  55. package/assets/js/modules/table.js +1 -1
  56. package/assets/js/scripts.bundle.js +15 -14
  57. package/assets/js/scripts.bundle.js.map +1 -1
  58. package/assets/js/scripts.bundle.min.js +2 -2
  59. package/assets/js/scripts.bundle.min.js.map +1 -1
  60. package/assets/sass/_corefiles.scss +2 -0
  61. package/assets/sass/_functions/mixins.scss +25 -0
  62. package/assets/sass/_functions/variables.scss +1 -1
  63. package/assets/sass/components/actionbar-global.scss +89 -0
  64. package/assets/sass/components/actionbar.scss +254 -0
  65. package/assets/sass/components/collapsible-side.scss +327 -0
  66. package/assets/sass/components/dialog.scss +10 -0
  67. package/assets/sass/components/forms.scss +29 -0
  68. package/assets/sass/components/nav-global.scss +630 -0
  69. package/assets/sass/components/nav.docs.scss +54 -0
  70. package/assets/sass/components/nav.old.scss +965 -0
  71. package/assets/sass/components/nav.scss +450 -782
  72. package/assets/sass/components/table.scss +9 -1
  73. package/assets/sass/foundations/buttons.scss +57 -32
  74. package/assets/sass/foundations/links.scss +1 -1
  75. package/assets/sass/foundations/reboot.scss +5 -3
  76. package/assets/ts/components/actionbar/README.md +55 -0
  77. package/assets/ts/components/actionbar/actionbar.component.ts +396 -0
  78. package/assets/ts/components/collapsible-side/README.md +38 -0
  79. package/assets/ts/components/collapsible-side/collapsible-side.component.ts +134 -0
  80. package/assets/ts/components/nav/README.md +68 -0
  81. package/assets/ts/components/nav/nav.component.ts +370 -0
  82. package/assets/ts/components/table/table.component.ts +65 -0
  83. package/assets/ts/modules/dialogs.ts +6 -0
  84. package/assets/ts/modules/helpers.ts +0 -17
  85. package/assets/ts/modules/table.ts +5 -5
  86. package/dist/components.es.js +1368 -1113
  87. package/dist/components.umd.js +188 -44
  88. package/dist/style.css +1 -1
  89. package/package.json +1 -1
  90. package/src/components/Actionbar/Actionbar.vue +20 -0
  91. package/src/components/Actionbar/README.md +40 -0
  92. package/src/components/CollapsibleSideMenu/CollapsibleSideMenu.vue +20 -0
  93. package/src/components/CollapsibleSideMenu/README.md +23 -0
  94. package/src/components/Nav/Nav.vue +20 -195
  95. package/src/components/Nav/README.md +43 -13
  96. package/src/components/Nav-old/Nav.vue +213 -0
  97. package/src/components/Nav-old/README.md +23 -0
  98. package/src/index.js +8 -0
  99. 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: var(--colour-canvas-2);
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: 2px solid var(--colour-btn-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(rem(12) - 2px) calc(rem(40) - 2px);
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
 
@@ -92,13 +95,18 @@ a:is(:hover, :focus, .hover, :active, .active):not([disabled]) .btn-secondary,
92
95
 
93
96
  // #region Action button
94
97
  .btn-action {
98
+
99
+ --btn-border-width: 1px;
100
+ --btn-padding-block: #{rem(6)};
101
+ --btn-padding-inline: #{rem(6)};
102
+
95
103
  background-color: var(--colour-canvas-2);
96
- border: 1px solid var(--colour-muted);
104
+ border: var(--btn-border-width) solid var(--colour-muted);
97
105
  border-radius: rem(4)!important;
98
106
  font-weight: 400!important;
99
107
  font-size: 1rem;
100
108
  line-height: rem(20);
101
- padding: rem(6);
109
+
102
110
  color: var(--colour-heading);
103
111
 
104
112
  &.btn[class*=fa-]:before {
@@ -128,14 +136,16 @@ a:is(:hover, :focus, .hover, :active, .active):not([disabled]) .btn-secondary,
128
136
 
129
137
  font-family: "Font Awesome 6 Pro";
130
138
  margin-right: 1rem;
139
+ line-height: 1em;
131
140
  }
132
141
 
133
- [class*="fa-"]{
142
+ i[class*="fa-"]{
134
143
 
135
144
  font-family: "Font Awesome 6 Pro";
136
145
  margin-right: 1rem;
137
-
146
+ line-height: 1em;
138
147
  font-style: inherit;
148
+
139
149
  &:not(:first-child){
140
150
  margin-left: 1rem;
141
151
  margin-right: 0;
@@ -178,41 +188,37 @@ a:is(:hover, :focus, .hover, :active, .active):not([disabled]) .btn-secondary,
178
188
  // #region button small and tag
179
189
  .btn.btn-sm {
180
190
 
181
- padding: em(8) em(32);
191
+ --btn-padding-block: #{rem(8)};
192
+ --btn-padding-inline: #{rem(32)};
182
193
  }
183
194
  // #endregion
184
195
 
185
196
  // #region btn compact
186
197
  .btn-compact {
187
- padding: calc(rem(12) - 2px)!important;
188
- margin-bottom: rem(8)!important;
189
- margin-right: rem(8)!important;
190
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
+ }
191
207
  text-align: center;
192
- width: calc(rem(48) - 4px);
193
- min-width: calc(rem(48) - 4px);
194
- max-width: calc(rem(48) - 4px);
195
- height: calc(rem(48) - 4px)!important;
196
- text-indent: -300px;
197
- overflow: hidden;
198
- position: relative;
199
- font-size: rem(20);
200
208
 
201
- &.btn-sm {
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;
202
215
 
203
- font-size: 1rem;
204
- padding: rem(6)!important;
205
- height: auto!important;
206
- line-height: rem(20);
207
- height: rem(20 + 6 + 6);
208
- width: rem(20 + 6 + 6);
209
- min-width: rem(20 + 6 + 6);
210
-
211
- &:before {
212
- line-height: rem(20 + 6 + 6);
213
- }
214
- }
216
+ line-height: calc(var(--compact-size) - var(--btn-border-width) - var(--btn-border-width))!important;
215
217
 
218
+ text-indent: -500px;
219
+ overflow: hidden;
220
+ position: relative;
221
+ font-size: rem(20);
216
222
 
217
223
  &:before {
218
224
  position: absolute;
@@ -221,10 +227,29 @@ a:is(:hover, :focus, .hover, :active, .active):not([disabled]) .btn-secondary,
221
227
  width: 100%;
222
228
  height: 100%;
223
229
  text-indent: 0;
224
- line-height: calc(3rem - 6px);
230
+ line-height: calc(var(--compact-size) - var(--btn-border-width) - var(--btn-border-width))!important;
225
231
  font-weight: 900;
226
232
  }
227
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
+
228
253
  &.btn-secondary {
229
254
 
230
255
  --colour-btn-border: transparent;
@@ -15,7 +15,7 @@ a {
15
15
  }
16
16
  }
17
17
 
18
- a:where(:not(.btn):not(:has(.card)):not(:has(iam-card))),
18
+ a:where(:not(.btn):not(.brand):not(:has(.card)):not(:has(iam-card))),
19
19
  .link {
20
20
  background-color: transparent;
21
21
  text-decoration: none;
@@ -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;