@iamproperty/components 3.6.0 → 3.7.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 (75) hide show
  1. package/assets/css/components/accordion.css.map +1 -1
  2. package/assets/css/components/admin-panel.css +1 -1
  3. package/assets/css/components/admin-panel.css.map +1 -1
  4. package/assets/css/components/card.css +1 -1
  5. package/assets/css/components/card.css.map +1 -1
  6. package/assets/css/components/dialog.css +1 -1
  7. package/assets/css/components/dialog.css.map +1 -1
  8. package/assets/css/components/forms.css.map +1 -1
  9. package/assets/css/components/lists.css +1 -1
  10. package/assets/css/components/lists.css.map +1 -1
  11. package/assets/css/components/table.css +1 -1
  12. package/assets/css/components/table.css.map +1 -1
  13. package/assets/css/core.min.css +1 -1
  14. package/assets/css/core.min.css.map +1 -1
  15. package/assets/css/style.min.css +1 -1
  16. package/assets/css/style.min.css.map +1 -1
  17. package/assets/js/bundle.js +2 -0
  18. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  19. package/assets/js/components/card/card.component.js +2 -2
  20. package/assets/js/components/card/card.component.min.js +4 -4
  21. package/assets/js/components/card/card.component.min.js.map +1 -1
  22. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  23. package/assets/js/components/header/header.component.min.js +1 -1
  24. package/assets/js/components/table/table.component.js +11 -8
  25. package/assets/js/components/table/table.component.min.js +5 -5
  26. package/assets/js/components/table/table.component.min.js.map +1 -1
  27. package/assets/js/components/tabs/tabs.component.min.js +2 -2
  28. package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
  29. package/assets/js/dynamic.js +3 -1
  30. package/assets/js/dynamic.min.js +2 -2
  31. package/assets/js/dynamic.min.js.map +1 -1
  32. package/assets/js/flat-components.js +2 -0
  33. package/assets/js/modules/dialogs.js +173 -0
  34. package/assets/js/modules/helpers.js +1 -89
  35. package/assets/js/modules/table.js +10 -8
  36. package/assets/js/modules/tabs.js +0 -2
  37. package/assets/js/scripts.bundle.js +24 -24
  38. package/assets/js/scripts.bundle.js.map +1 -1
  39. package/assets/js/scripts.bundle.min.js +2 -2
  40. package/assets/js/scripts.bundle.min.js.map +1 -1
  41. package/assets/js/tests/table.spec.js +15 -0
  42. package/assets/sass/_functions/variables.scss +3 -28
  43. package/assets/sass/components/admin-panel.scss +0 -10
  44. package/assets/sass/components/card.scss +32 -25
  45. package/assets/sass/components/dialog.scss +332 -28
  46. package/assets/sass/components/lists.scss +16 -33
  47. package/assets/sass/components/table.scss +47 -41
  48. package/assets/sass/foundations/buttons.scss +9 -13
  49. package/assets/sass/foundations/icons.scss +14 -69
  50. package/assets/sass/foundations/reboot.scss +12 -4
  51. package/assets/sass/foundations/root.scss +9 -0
  52. package/assets/sass/helpers/max-height.scss +15 -0
  53. package/assets/ts/bundle.ts +2 -0
  54. package/assets/ts/components/card/README.md +2 -1
  55. package/assets/ts/components/card/card.component.ts +2 -2
  56. package/assets/ts/components/table/table.component.ts +12 -9
  57. package/assets/ts/dynamic.ts +3 -1
  58. package/assets/ts/flat-components.ts +2 -0
  59. package/assets/ts/html.d.ts +7 -1
  60. package/assets/ts/modules/dialogs.ts +237 -0
  61. package/assets/ts/modules/helpers.ts +1 -123
  62. package/assets/ts/modules/table.ts +14 -13
  63. package/assets/ts/modules/tabs.ts +0 -4
  64. package/assets/ts/tests/table.spec.ts +15 -0
  65. package/dist/components.es.js +982 -1003
  66. package/dist/components.umd.js +25 -21
  67. package/package.json +2 -3
  68. package/src/components/Card/Card.vue +2 -2
  69. package/src/components/Card/README.md +1 -1
  70. package/src/components/Nav/Nav.vue +1 -3
  71. package/src/index.js +0 -1
  72. package/assets/svg/icons.svg +0 -599
  73. package/src/foundations/Icon/Icon.spec.js +0 -24
  74. package/src/foundations/Icon/Icon.vue +0 -24
  75. package/src/foundations/Icon/README.md +0 -11
@@ -0,0 +1,237 @@
1
+ // @ts-nocheck
2
+ import { createEmbed } from "./youtubevideo";
3
+
4
+ const extendDialogs = (body) => {
5
+
6
+ // Dialogs/modals
7
+ body.addEventListener('click', (event) => {
8
+
9
+ // Modal
10
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-modal]')){
11
+
12
+ const button = event.target.closest('[data-modal]');
13
+ const modalID = button.hasAttribute('data-modal') ? button.getAttribute('data-modal') : button.getAttribute('data-filter');
14
+ const dialog = document.querySelector(`dialog#${modalID}`);
15
+
16
+ createDialog(dialog);
17
+
18
+
19
+ // Prevent the user from escaping the model when transactional
20
+ if(dialog.querySelector(':scope > .mh-lg > form:last-child > button:last-child, :scope > .mh-lg > button:last-child') && !dialog.classList.contains('dialog--multi')) {
21
+ dialog.addEventListener("cancel", (e) => {
22
+ e.preventDefault();
23
+ });
24
+ }
25
+
26
+ // Create the video embed
27
+ let videoButton = dialog.querySelector('.youtube-embed a');
28
+ if (videoButton){
29
+ createEmbed(videoButton)
30
+ }
31
+
32
+ // Open the modal!
33
+ dialog.showModal();
34
+
35
+ dialog.focus();
36
+
37
+ console.log(dialog.querySelector('button'));
38
+
39
+ window.dataLayer = window.dataLayer || [];
40
+ window.dataLayer.push({
41
+ "event": "openModal",
42
+ "id": modalID
43
+ });
44
+ };
45
+
46
+ // Close modal
47
+ if (event && event.target instanceof HTMLElement && event.target.closest('button.dialog__close')){
48
+ const dialog = event.target.closest('dialog[open]');
49
+
50
+ event.preventDefault();
51
+ dialog.close()
52
+
53
+ window.dataLayer = window.dataLayer || [];
54
+ window.dataLayer.push({
55
+ "event": "closeModal",
56
+ "id": dialog.getAttribute('id')
57
+ });
58
+ }
59
+
60
+ // Track default close buttons
61
+ if (event && event.target instanceof HTMLElement && event.target.closest('button[formmethod="dialog"]')){
62
+ const dialog = event.target.closest('dialog[open]');
63
+
64
+ window.dataLayer = window.dataLayer || [];
65
+ window.dataLayer.push({
66
+ "event": "closeModal",
67
+ "id": dialog.getAttribute('id')
68
+ });
69
+ }
70
+
71
+ // Close the modal when clicked on the backdrop
72
+ if (event && event.target instanceof HTMLElement && event.target.closest('dialog[open]')){
73
+ const dialog = event.target.closest('dialog[open]');
74
+
75
+ // Dont allow the backdrop to be clicked when transactional
76
+ if(!dialog.querySelector(':scope > .mh-lg > form:last-child > button:last-child, :scope > .mh-lg > button:last-child') || dialog.classList.contains('dialog--multi')){
77
+
78
+ const dialogDimensions = dialog.getBoundingClientRect()
79
+
80
+ if (event.clientX < dialogDimensions.left || event.clientX > dialogDimensions.right || event.clientY < dialogDimensions.top || event.clientY > dialogDimensions.bottom) {
81
+
82
+ dialog.close()
83
+
84
+ window.dataLayer = window.dataLayer || [];
85
+ window.dataLayer.push({
86
+ "event": "closeModal",
87
+ "id": dialog.getAttribute('id')
88
+ });
89
+ }
90
+ }
91
+ }
92
+
93
+ // Popover
94
+ if (event && event.target instanceof HTMLElement && event.target.closest('.dialog__wrapper > button')){
95
+
96
+ // Close existing open popover
97
+
98
+ let btn = event.target.closest('.dialog__wrapper > button');
99
+ let parent = event.target.closest('.dialog__wrapper > button').parentNode;
100
+ let dataEvent = "openPopover"
101
+ let popover = parent.querySelector(':scope > dialog');
102
+
103
+
104
+ if(document.querySelector('dialog[open]') && document.querySelector('dialog[open]') != popover)
105
+ document.querySelector('dialog[open]').close();
106
+
107
+
108
+ if(popover.hasAttribute('open')){
109
+
110
+ popover.close();
111
+ dataEvent = "closePopover"
112
+
113
+ popover.removeAttribute('style');
114
+ btn.classList.remove('active');
115
+ }
116
+ else {
117
+
118
+ popover.show();
119
+ btn.classList.add('active');
120
+
121
+ var position = btn.getBoundingClientRect();
122
+ let topOffset = position.top;
123
+ let leftOffset = position.left;
124
+
125
+ if(btn.closest('iam-table')){
126
+
127
+ let container = btn.closest('iam-table').parentNode.getBoundingClientRect();
128
+
129
+ topOffset -= container.top;
130
+ leftOffset -= container.left;
131
+
132
+ }
133
+
134
+ if(popover.classList.contains('dialog--fix')){
135
+ popover.setAttribute('style',`position:fixed;top: ${topOffset}px; left: ${leftOffset}px; margin: 3rem 0 0 0;`)
136
+ }
137
+ }
138
+
139
+ // When the dialog is fixed it could dip under the viewport
140
+ // Lets check the dimensions and transform it to appear above
141
+ let boundingRec = popover.getBoundingClientRect();
142
+ let popoverBottom = boundingRec.bottom - window.scrollY;
143
+ let windowPos = window.innerHeight - window.scrollY;
144
+ if(popoverBottom > windowPos){
145
+
146
+ let currentStyle = popover.getAttribute('style');
147
+
148
+ popover.setAttribute('style',currentStyle+`transform: translate(0, calc(-100% - 4rem))`);
149
+ }
150
+
151
+ window.dataLayer = window.dataLayer || [];
152
+
153
+ window.dataLayer.push({
154
+ "event": dataEvent,
155
+ "id": btn.textContent
156
+ });
157
+ };
158
+ });
159
+
160
+ return null
161
+ }
162
+
163
+ export const createDialog = (dialog) => {
164
+
165
+ // Multi dialog
166
+ if(dialog.classList.contains('dialog--multi') && !dialog.querySelector(':scope > .steps')) {
167
+ createMultiFormDialog(dialog);
168
+ }
169
+
170
+ if(!dialog.querySelector(':scope > .mh-lg') && !dialog.classList.contains('dialog--multi')){
171
+ dialog.innerHTML = `<div class="mh-lg">${dialog.innerHTML}</div>`;
172
+
173
+ let dialogContent = dialog.querySelector('.mh-lg');
174
+ let titleElement = dialog.querySelector('.mh-lg :is(.h1,.h2,.h3,.h4,.h5,.h6)');
175
+
176
+ if(titleElement){
177
+
178
+ let optionalElement = titleElement.previousSibling;
179
+
180
+ dialogContent.before(titleElement);
181
+
182
+ if(optionalElement)
183
+ titleElement.before(optionalElement);
184
+ }
185
+ }
186
+
187
+ // Create close button is needed
188
+ if(!dialog.querySelector(':scope > button:first-child'))
189
+ dialog.innerHTML = `<button class="dialog__close">Close</button>${dialog.innerHTML}`;
190
+
191
+ }
192
+
193
+ const createMultiFormDialog = (dialog) => {
194
+ let buttons = "";
195
+ let fieldsets = Array.from(dialog.querySelectorAll('fieldset[data-title]'));
196
+ fieldsets.forEach((fieldset,index) => {
197
+ buttons += `<button data-title="${fieldset.getAttribute('data-title')}" type="button" class="${index == 0 ? "active":""}">${fieldset.getAttribute('data-title')}</button>`;
198
+
199
+ const btnWrapper = document.createElement("div");
200
+ btnWrapper.classList.add('btn--wrapper');
201
+ fieldset.appendChild(btnWrapper);
202
+
203
+
204
+ if(index != 0)
205
+ btnWrapper.innerHTML += `<button data-title="${fieldsets[index-1].getAttribute('data-title')}" class="btn btn-secondary mb-0" type="button">Previous</button>`;
206
+
207
+ if(index != fieldsets.length - 1)
208
+ btnWrapper.innerHTML += `<button data-title="${fieldsets[index+1].getAttribute('data-title')}" class="btn btn-primary mb-0" type="button">Next</button>`;
209
+
210
+ if(index == fieldsets.length - 1)
211
+ btnWrapper.innerHTML += `<button class="btn btn-primary mb-0">Submit</button>`;
212
+ });
213
+
214
+ dialog.innerHTML = `<div class="steps bg-primary">${buttons}</div>${dialog.innerHTML}`;
215
+
216
+
217
+ dialog.addEventListener('click', (event) => {
218
+ if (event && event.target instanceof HTMLElement && event.target.closest('button[data-title]')){
219
+ const button = event.target.closest('button[data-title]');
220
+ const fieldset = dialog.querySelector(`fieldset[data-title="${button.getAttribute('data-title')}"]`);
221
+ const step = dialog.querySelector(`.steps button[data-title="${button.getAttribute('data-title')}"]`);
222
+
223
+ Array.from(dialog.querySelectorAll('button')).forEach((button, index) => {
224
+ button.classList.remove('active');
225
+ });
226
+ Array.from(dialog.querySelectorAll('fieldset')).forEach((button, index) => {
227
+ button.classList.remove('active');
228
+ });
229
+
230
+ step.classList.add('active');
231
+ fieldset.classList.add('active');
232
+ };
233
+ return null
234
+ });
235
+ }
236
+
237
+ export default extendDialogs;
@@ -1,6 +1,4 @@
1
1
  // @ts-nocheck
2
- import { createEmbed } from "./youtubevideo";
3
-
4
2
  /**
5
3
  * Global helper functions to help maintain and enhance framework elements.
6
4
  * @module Helpers
@@ -49,7 +47,7 @@ export const addGlobalEvents = (body) => {
49
47
 
50
48
  addEventListener("popstate", (event) => {
51
49
 
52
- if(event.state.type == "pagination"){
50
+ if(event && event.state.type && event.state.type == "pagination"){
53
51
  let form = document.querySelector(`#${event.state.form}`);
54
52
  let pageInput = document.querySelector(`#${event.state.form} [data-pagination]`);
55
53
 
@@ -62,126 +60,6 @@ export const addGlobalEvents = (body) => {
62
60
  }
63
61
  });
64
62
 
65
- // Dialogs/modals
66
- document.addEventListener('click', (event) => {
67
-
68
- // Modal
69
- if (event && event.target instanceof HTMLElement && event.target.closest('[data-modal]')){
70
-
71
- const button = event.target.closest('[data-modal]');
72
- const modalID = button.hasAttribute('data-modal') ? button.getAttribute('data-modal') : button.getAttribute('data-filter');
73
- const dialog = document.querySelector(`dialog#${modalID}`);
74
-
75
- // Create close button is needed
76
- dialog.innerHTML = `<button class="dialog__close">Close</button>${dialog.innerHTML}`;
77
-
78
- // remove close button when dialog is closed
79
- dialog.addEventListener("close", () => {
80
- const closeButton = dialog.querySelector('.dialog__close');
81
- dialog.removeChild(closeButton);
82
- }, { once: true }); // only adds this once
83
-
84
- let videoButton = dialog.querySelector('.youtube-embed a');
85
-
86
- if (videoButton){
87
- createEmbed(videoButton)
88
- }
89
-
90
- dialog.showModal();
91
-
92
- window.dataLayer = window.dataLayer || [];
93
- window.dataLayer.push({
94
- "event": "openModal",
95
- "id": modalID
96
- });
97
- };
98
-
99
- // Close modal
100
- if (event && event.target instanceof HTMLElement && event.target.closest('button.dialog__close')){
101
- const dialog = event.target.closest('dialog[open]');
102
-
103
- event.preventDefault();
104
- dialog.close()
105
-
106
- window.dataLayer = window.dataLayer || [];
107
- window.dataLayer.push({
108
- "event": "closeModal",
109
- "id": dialog.getAttribute('id')
110
- });
111
- }
112
-
113
- if (event && event.target instanceof HTMLElement && event.target.closest('dialog[open]')){
114
- const dialog = event.target.closest('dialog[open]');
115
- const dialogDimensions = dialog.getBoundingClientRect()
116
-
117
- if (event.clientX < dialogDimensions.left || event.clientX > dialogDimensions.right || event.clientY < dialogDimensions.top || event.clientY > dialogDimensions.bottom) {
118
-
119
- dialog.close()
120
-
121
- window.dataLayer = window.dataLayer || [];
122
- window.dataLayer.push({
123
- "event": "closeModal",
124
- "id": dialog.getAttribute('id')
125
- });
126
- }
127
- }
128
-
129
- // Popover
130
- if (event && event.target instanceof HTMLElement && event.target.closest('.dialog__wrapper > button')){
131
-
132
- // Close existing open popover
133
-
134
- let btn = event.target.closest('.dialog__wrapper > button');
135
- let parent = event.target.closest('.dialog__wrapper > button').parentNode;
136
- let dataEvent = "openPopover"
137
- let popover = parent.querySelector(':scope > dialog');
138
-
139
-
140
- if(document.querySelector('dialog[open]') && document.querySelector('dialog[open]') != popover)
141
- document.querySelector('dialog[open]').close();
142
-
143
-
144
- if(popover.hasAttribute('open')){
145
-
146
- popover.close();
147
- dataEvent = "closePopover"
148
-
149
- popover.removeAttribute('style');
150
- btn.classList.remove('active');
151
- }
152
- else {
153
-
154
- popover.show();
155
- btn.classList.add('active');
156
-
157
- var position = btn.getBoundingClientRect();
158
- let topOffset = position.top;
159
- let leftOffset = position.left;
160
-
161
- if(btn.closest('iam-table')){
162
-
163
- let container = btn.closest('iam-table').parentNode.getBoundingClientRect();
164
-
165
- topOffset -= container.top;
166
- leftOffset -= container.left;
167
-
168
- }
169
-
170
- if(popover.classList.contains('dialog--fix')){
171
- popover.setAttribute('style',`position:fixed;top: ${topOffset}px; left: ${leftOffset}px; margin: 3rem 0 0 0;`)
172
- }
173
- }
174
-
175
-
176
- window.dataLayer = window.dataLayer || [];
177
-
178
- window.dataLayer.push({
179
- "event": dataEvent,
180
- "id": btn.textContent
181
- });
182
- };
183
- });
184
-
185
63
  return null
186
64
  }
187
65
 
@@ -67,14 +67,17 @@ export const createMobileButton = (table) => {
67
67
  if(table.closest('.table--fullwidth'))
68
68
  return false;
69
69
 
70
+ if(table.querySelectorAll('thead tr th').length < 4)
71
+ return false;
72
+
70
73
  Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
71
74
  let firstCol = row.querySelector(':scope > :is(td,th):first-child');
75
+
72
76
  let colContent = firstCol.textContent;
73
77
 
74
78
  if(colContent != "")
75
79
  firstCol.innerHTML =`<span class="td__content">${colContent}</span><button type="button" class="d-none">${colContent}</button>`;
76
80
  else {
77
-
78
81
  let secondCol = row.querySelector(':scope > :is(td,th):nth-child(2)');
79
82
  let secondColContent = secondCol.textContent;
80
83
  secondCol.innerHTML =`<span class="td__content">${secondColContent}</span><button type="button" class="d-none">${secondColContent}</button>`;
@@ -383,16 +386,9 @@ export const filterTable = (table, form, wrapper) => {
383
386
  element.innerHTML += `(${filters.length})`;
384
387
  });
385
388
  }
386
-
387
- // Stop function if no filters identified
388
- if(!Object.keys(searches).length && !Object.keys(filters).length)
389
- return false;
390
389
 
391
- table.classList.add('table--filtered');
392
-
393
-
394
390
  // Filter the table
395
-
391
+ table.classList.add('table--filtered');
396
392
  for (const [key, filterValue] of Object.entries(filters)) {
397
393
 
398
394
  Array.from(table.querySelectorAll('tbody tr:not(.filtered)')).forEach((row, index) => {
@@ -504,8 +500,10 @@ export const filterTable = (table, form, wrapper) => {
504
500
  matched++;
505
501
 
506
502
  row.classList.add('filtered--matched');
503
+
507
504
  // pagination bit
508
- if(Math.ceil(matched/showRows) == parseInt(page))
505
+ let matchesPage = Math.ceil(matched/showRows);
506
+ if(matchesPage == parseInt(page))
509
507
  row.classList.add('filtered--show');
510
508
  });
511
509
 
@@ -595,9 +593,12 @@ export const addPaginationEventListeners = function(table, form, pagination, wra
595
593
  wrapper.setAttribute('data-page', newPage);
596
594
  form.dispatchEvent(new Event("submit"));
597
595
 
598
- const url = new URL(location);
599
- url.searchParams.set("page", newPage);
600
- history.pushState({'type':'pagination','form':form.getAttribute('id'),'page':newPage}, "", url)
596
+ if(table.hasAttribute('data-show-history')){
597
+
598
+ const url = new URL(location);
599
+ url.searchParams.set("page", newPage);
600
+ history.pushState({'type':'pagination','form':form.getAttribute('id'),'page':newPage}, "", url)
601
+ }
601
602
  }
602
603
 
603
604
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-show]')){
@@ -51,15 +51,11 @@ export const setTabsEventHandlers = function(tabsElement: Element){
51
51
  if(tabsElement.shadowRoot)
52
52
  buttons = tabsElement.shadowRoot.querySelectorAll('.tabs__links > .link');
53
53
 
54
- console.log(buttons)
55
-
56
54
  // Set the on click for the tab buttons, these will open the details box it matches too
57
55
  buttons.forEach((button) => {
58
56
 
59
57
  button.addEventListener("click", (e) => {
60
58
 
61
- console.log('hi')
62
-
63
59
  e.preventDefault();
64
60
  buttons.forEach((buttonLoopItem) => {
65
61
 
@@ -9,6 +9,9 @@ const basicTable = `<thead>
9
9
  <th>Heading 1</th>
10
10
  <th>Heading 2</th>
11
11
  <th>Heading 3</th>
12
+ <th>Heading 4</th>
13
+ <th>Heading 5</th>
14
+ <th>Heading 6</th>
12
15
  </tr>
13
16
  </thead>
14
17
  <tbody>
@@ -16,21 +19,33 @@ const basicTable = `<thead>
16
19
  <td>Cell 1</td>
17
20
  <td>Low</td>
18
21
  <td>Cell 3</td>
22
+ <td>Cell 4</td>
23
+ <td>Cell 5</td>
24
+ <td>Cell 6</td>
19
25
  </tr>
20
26
  <tr>
21
27
  <td>Cell 1</td>
22
28
  <td>Low</td>
23
29
  <td><a href="/link">View information</a></td>
30
+ <td>Cell 4</td>
31
+ <td>Cell 5</td>
32
+ <td>Cell 6</td>
24
33
  </tr>
25
34
  <tr>
26
35
  <td>Different Cell 1</td>
27
36
  <td>Medium</td>
28
37
  <td><a href="/link">View information</a></td>
38
+ <td>Cell 4</td>
39
+ <td>Cell 5</td>
40
+ <td>Cell 6</td>
29
41
  </tr>
30
42
  <tr>
31
43
  <td>Different Cell 1</td>
32
44
  <td>High</td>
33
45
  <td><a href="/link">View information</a></td>
46
+ <td>Cell 4</td>
47
+ <td>Cell 5</td>
48
+ <td>Cell 6</td>
34
49
  </tr>
35
50
  </tbody>`;
36
51