@iamproperty/components 3.4.5 → 3.4.7

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 (203) hide show
  1. package/assets/css/components/accordion.css +1 -0
  2. package/assets/css/components/accordion.css.map +1 -0
  3. package/assets/css/components/alert.css +1 -0
  4. package/assets/css/components/alert.css.map +1 -0
  5. package/assets/css/components/applied-filters.css +1 -0
  6. package/assets/css/components/applied-filters.css.map +1 -0
  7. package/assets/css/components/buttons.css +1 -0
  8. package/assets/css/components/buttons.css.map +1 -0
  9. package/assets/css/components/card.css +1 -0
  10. package/assets/css/components/card.css.map +1 -0
  11. package/assets/css/components/carousel.css +1 -0
  12. package/assets/css/components/carousel.css.map +1 -0
  13. package/assets/css/components/charts.css +1 -0
  14. package/assets/css/components/charts.css.map +1 -0
  15. package/assets/css/components/container.css +1 -0
  16. package/assets/css/components/container.css.map +1 -0
  17. package/assets/css/components/dialog.css +1 -0
  18. package/assets/css/components/dialog.css.map +1 -0
  19. package/assets/css/components/forms.css +1 -0
  20. package/assets/css/components/forms.css.map +1 -0
  21. package/assets/css/components/header.css +1 -0
  22. package/assets/css/components/header.css.map +1 -0
  23. package/assets/css/components/lists.css +1 -0
  24. package/assets/css/components/lists.css.map +1 -0
  25. package/assets/css/components/nav.css +1 -0
  26. package/assets/css/components/nav.css.map +1 -0
  27. package/assets/css/components/pagination.css +1 -0
  28. package/assets/css/components/pagination.css.map +1 -0
  29. package/assets/css/components/panel.css +1 -0
  30. package/assets/css/components/panel.css.map +1 -0
  31. package/assets/css/components/property-searchbar.css +1 -0
  32. package/assets/css/components/property-searchbar.css.map +1 -0
  33. package/assets/css/components/snapshot.css +1 -0
  34. package/assets/css/components/snapshot.css.map +1 -0
  35. package/assets/css/components/stepper.css +1 -0
  36. package/assets/css/components/stepper.css.map +1 -0
  37. package/assets/css/components/table.css +1 -0
  38. package/assets/css/components/table.css.map +1 -0
  39. package/assets/css/components/tabs.css +1 -0
  40. package/assets/css/components/tabs.css.map +1 -0
  41. package/assets/css/components/testimonial.css +1 -0
  42. package/assets/css/components/testimonial.css.map +1 -0
  43. package/assets/css/components/timeline.css +1 -0
  44. package/assets/css/components/timeline.css.map +1 -0
  45. package/assets/css/components/tooltips.css +1 -0
  46. package/assets/css/components/tooltips.css.map +1 -0
  47. package/assets/css/core.min.css +1 -1
  48. package/assets/css/core.min.css.map +1 -1
  49. package/assets/css/style.min.css +1 -1
  50. package/assets/css/style.min.css.map +1 -1
  51. package/assets/fonts/qanelas-bold-webfont.woff +0 -0
  52. package/assets/fonts/qanelas-bold-webfont.woff2 +0 -0
  53. package/assets/js/bundle.js +68 -0
  54. package/assets/js/components/accordion/accordion.component.js +33 -0
  55. package/assets/js/components/accordion/accordion.component.min.js +14 -0
  56. package/assets/js/components/accordion/accordion.component.min.js.map +1 -0
  57. package/assets/js/components/applied-filters/applied-filters.component.js +26 -0
  58. package/assets/js/components/card/card.component.js +91 -0
  59. package/assets/js/components/card/card.component.min.js +21 -0
  60. package/assets/js/components/card/card.component.min.js.map +1 -0
  61. package/assets/js/components/filterlist/filterlist.component.js +49 -0
  62. package/assets/js/components/filterlist/filterlist.component.min.js +23 -0
  63. package/assets/js/components/filterlist/filterlist.component.min.js.map +1 -0
  64. package/assets/js/components/header/header.component.js +51 -0
  65. package/assets/js/components/header/header.component.min.js +30 -0
  66. package/assets/js/components/header/header.component.min.js.map +1 -0
  67. package/assets/js/components/pagination/pagination.component.js +34 -0
  68. package/assets/js/components/table/table.component.js +104 -0
  69. package/assets/js/components/table/table.component.min.js +24 -0
  70. package/assets/js/components/table/table.component.min.js.map +1 -0
  71. package/assets/js/components/tabs/tabs.component.js +34 -0
  72. package/assets/js/components/tabs/tabs.component.min.js +17 -0
  73. package/assets/js/components/tabs/tabs.component.min.js.map +1 -0
  74. package/assets/js/dynamic.js +74 -0
  75. package/assets/js/dynamic.min.js +5 -0
  76. package/assets/js/dynamic.min.js.map +1 -0
  77. package/assets/js/flat-components.js +79 -0
  78. package/assets/js/modules/accordion.js +11 -14
  79. package/assets/js/modules/applied-filters.js +100 -0
  80. package/assets/js/modules/data-layer.js +45 -0
  81. package/assets/js/modules/filterlist.js +32 -0
  82. package/assets/js/modules/helpers.js +80 -47
  83. package/assets/js/modules/pagination.js +33 -0
  84. package/assets/js/modules/table.js +507 -420
  85. package/assets/js/modules/tabs.js +97 -0
  86. package/assets/js/modules/youtubevideo.js +53 -61
  87. package/assets/js/scripts.bundle.js +111 -984
  88. package/assets/js/scripts.bundle.js.map +1 -1
  89. package/assets/js/scripts.bundle.min.js +3 -4
  90. package/assets/js/scripts.bundle.min.js.map +1 -1
  91. package/assets/js/tests/filterlist.spec.js +22 -0
  92. package/assets/js/tests/pagination.spec.js +15 -0
  93. package/assets/js/tests/table.spec.js +147 -0
  94. package/assets/sass/_components.scss +1 -2
  95. package/assets/sass/_corefiles.scss +5 -4
  96. package/assets/sass/_fonts.scss +4 -4
  97. package/assets/sass/_func.scss +1 -0
  98. package/assets/sass/_functions/functions.scss +6 -0
  99. package/assets/sass/_functions/mixins.scss +9 -9
  100. package/assets/sass/_functions/utilities.scss +16 -0
  101. package/assets/sass/_functions/variables.scss +128 -86
  102. package/assets/sass/_tests/colours.spec.scss +1 -1
  103. package/assets/sass/_tests/mixins.spec.scss +1 -1
  104. package/assets/sass/_tests/typography.spec.scss +2 -2
  105. package/assets/sass/components/accordion.scss +9 -6
  106. package/assets/sass/components/applied-filters.scss +65 -0
  107. package/assets/sass/components/card.scss +178 -227
  108. package/assets/sass/components/charts.scss +4 -0
  109. package/assets/sass/components/container.scss +13 -8
  110. package/assets/sass/components/dialog.scss +202 -0
  111. package/assets/sass/components/forms.scss +39 -5
  112. package/assets/sass/components/header.scss +34 -11
  113. package/assets/sass/components/lists.scss +15 -0
  114. package/assets/sass/components/nav.scss +5 -1
  115. package/assets/sass/components/pagination.scss +140 -0
  116. package/assets/sass/components/panel.scss +3 -4
  117. package/assets/sass/components/snapshot.scss +1 -1
  118. package/assets/sass/components/table.scss +419 -0
  119. package/assets/sass/components/tabs.scss +52 -36
  120. package/assets/sass/components/timeline.scss +2 -2
  121. package/assets/sass/foundations/icons.scss +1 -1
  122. package/assets/sass/{components → foundations}/links.scss +29 -2
  123. package/assets/sass/foundations/reboot.scss +21 -15
  124. package/assets/sass/foundations/root.scss +12 -5
  125. package/assets/sass/foundations/type.scss +90 -66
  126. package/assets/svg/illustrations/table.svg +165 -0
  127. package/assets/ts/README.md +12 -0
  128. package/assets/ts/bundle.ts +87 -0
  129. package/assets/ts/components/accordion/README.md +17 -0
  130. package/assets/ts/components/accordion/accordion.component.ts +43 -0
  131. package/assets/ts/components/applied-filters/README.md +5 -0
  132. package/assets/ts/components/applied-filters/applied-filters.component.ts +33 -0
  133. package/assets/ts/components/card/README.md +22 -0
  134. package/assets/ts/components/card/card.component.ts +117 -0
  135. package/assets/ts/components/filterlist/README.md +17 -0
  136. package/assets/ts/components/filterlist/filterlist.component.ts +60 -0
  137. package/assets/ts/components/header/README.md +26 -0
  138. package/assets/ts/components/header/header.component.ts +61 -0
  139. package/assets/ts/components/pagination/README.md +11 -0
  140. package/assets/ts/components/pagination/pagination.component.ts +45 -0
  141. package/assets/ts/components/table/README.md +23 -0
  142. package/assets/ts/components/table/table.component.ts +128 -0
  143. package/assets/ts/components/tabs/README.md +18 -0
  144. package/assets/ts/components/tabs/tabs.component.ts +41 -0
  145. package/assets/ts/dynamic.ts +98 -0
  146. package/assets/ts/flat-components.ts +100 -0
  147. package/assets/ts/html.d.ts +4 -0
  148. package/assets/ts/modules/accordion.ts +15 -21
  149. package/assets/ts/modules/applied-filters.ts +146 -0
  150. package/assets/ts/modules/data-layer.ts +58 -0
  151. package/assets/ts/modules/filterlist.ts +46 -0
  152. package/assets/ts/modules/helpers.ts +93 -55
  153. package/assets/ts/modules/pagination.ts +44 -0
  154. package/assets/ts/modules/table.ts +598 -433
  155. package/assets/ts/modules/tabs.ts +136 -0
  156. package/assets/ts/modules/youtubevideo.ts +58 -63
  157. package/assets/ts/tests/filterlist.spec.ts +29 -0
  158. package/assets/ts/tests/pagination.spec.ts +21 -0
  159. package/assets/ts/tests/table.spec.ts +191 -0
  160. package/dist/components.es.js +1359 -1356
  161. package/dist/components.umd.js +103 -54
  162. package/dist/style.css +1 -1
  163. package/package.json +20 -12
  164. package/src/components/Accordion/Accordion.spec.js +1 -1
  165. package/src/components/Accordion/Accordion.vue +7 -5
  166. package/src/components/Accordion/AccordionItem.vue +3 -6
  167. package/src/components/Accordion/README.md +0 -2
  168. package/src/components/AppliedFilters/AppliedFilters.vue +20 -0
  169. package/src/components/AppliedFilters/README.md +5 -0
  170. package/src/components/Card/Card.vue +11 -112
  171. package/src/components/Card/README.md +16 -18
  172. package/src/components/Carousel/Carousel.vue +49 -10
  173. package/src/components/Chart/Chart.vue +46 -4
  174. package/src/components/Filterlist/Filterlist.vue +20 -0
  175. package/src/components/Filterlist/README.md +17 -0
  176. package/src/components/Header/Header.spec.js +5 -4
  177. package/src/components/Header/Header.vue +14 -20
  178. package/src/components/Pagination/Pagination.vue +30 -0
  179. package/src/components/Pagination/README.md +11 -0
  180. package/src/components/Snapshot/Snapshot.vue +1 -1
  181. package/src/components/Table/README.md +29 -44
  182. package/src/components/Table/Table.spec.js +5 -37
  183. package/src/components/Table/Table.vue +16 -91
  184. package/src/components/Tabs/README.md +0 -2
  185. package/src/components/Tabs/Tab.vue +3 -2
  186. package/src/components/Tabs/Tabs.vue +8 -64
  187. package/src/foundations/YoutubeVideo/YoutubeVideo.vue +1 -1
  188. package/src/index.js +3 -2
  189. package/assets/fonts/qanelassoft-extrabold-webfont.woff +0 -0
  190. package/assets/fonts/qanelassoft-extrabold-webfont.woff2 +0 -0
  191. package/assets/js/main.js +0 -57
  192. package/assets/js/modules/modal.js +0 -69
  193. package/assets/sass/components/cardDeck.scss +0 -108
  194. package/assets/sass/components/modal.scss +0 -136
  195. package/assets/sass/components/tables.scss +0 -291
  196. package/assets/ts/main.ts +0 -68
  197. package/assets/ts/modules/modal.ts +0 -91
  198. package/src/components/CardDeck/CardDeck.spec.js +0 -99
  199. package/src/components/CardDeck/CardDeck.vue +0 -77
  200. package/src/components/CardDeck/README.md +0 -25
  201. package/src/components/Modal/Modal.spec.js +0 -22
  202. package/src/components/Modal/Modal.vue +0 -43
  203. package/src/components/Modal/README.md +0 -20
@@ -0,0 +1,136 @@
1
+ // @ts-nocheck
2
+ export const createTabsLinks = function(tabsElement: Element) {
3
+
4
+ const details = tabsElement.querySelectorAll(':scope > details');
5
+ let summaries = tabsElement.querySelectorAll(':scope > details > summary');
6
+ let tabLinks = tabsElement.querySelector(':scope > .tabs__links');
7
+
8
+ if(tabsElement.shadowRoot && tabsElement.shadowRoot.querySelector('.tabs__links'))
9
+ tabLinks = tabsElement.shadowRoot.querySelector('.tabs__links');
10
+
11
+ if(!tabLinks){
12
+ tabLinks = document.createElement('div');
13
+ tabLinks.classList.add('tabs__links');
14
+
15
+ tabsElement.prepend(tabLinks);
16
+ }
17
+
18
+ // Create the tab buttons from the summary titles
19
+ details.forEach((detail, index) => {
20
+
21
+ let summary = detail.querySelector(':scope > summary');
22
+ summary.classList.add('visually-hidden');
23
+
24
+ let button = document.createElement('button');
25
+ if(detail.hasAttribute('id')){
26
+
27
+ button = document.createElement('a');
28
+ button.setAttribute('href',`#${detail.getAttribute('id')}`);
29
+ }
30
+
31
+ if(detail.hasAttribute('open')){
32
+ button.setAttribute('aria-pressed',true);
33
+ }
34
+
35
+ button.innerHTML = `${summary.innerText}`;
36
+ button.classList.add('link');
37
+ button.setAttribute('data-index',index);
38
+ button.setAttribute('tabindex','-1');
39
+
40
+ tabLinks.appendChild(button);
41
+ });
42
+
43
+ }
44
+
45
+ export const setTabsEventHandlers = function(tabsElement: Element){
46
+
47
+ let details = tabsElement.querySelectorAll(':scope > details');
48
+ let summaries = tabsElement.querySelectorAll(':scope > details > summary');
49
+ let buttons = tabsElement.querySelectorAll(':scope > .tabs__links > button, .tabs__links > a');
50
+
51
+ if(tabsElement.shadowRoot)
52
+ buttons = tabsElement.shadowRoot.querySelectorAll('.tabs__links > button, .tabs__links > a');
53
+
54
+ // Set the on click for the tab buttons, these will open the details box it matches too
55
+ buttons.forEach((button) => {
56
+
57
+ button.addEventListener("click", (e) => {
58
+ e.preventDefault();
59
+ buttons.forEach((buttonLoopItem) => {
60
+
61
+ let buttonPressed = buttonLoopItem == button ? true : false;
62
+ buttonLoopItem.setAttribute('aria-pressed', buttonPressed);
63
+ });
64
+ details.forEach((detail, detailsIndex) => {
65
+
66
+ let detailsOpen = button.getAttribute('data-index') == detailsIndex ? true : false;
67
+
68
+ if(detailsOpen)
69
+ detail.setAttribute('open', detailsOpen);
70
+ else
71
+ detail.removeAttribute('open')
72
+ });
73
+
74
+ if(button.hasAttribute('href'))
75
+ history.pushState(undefined, undefined, button.getAttribute('href'));
76
+
77
+ // Data layer Open Event
78
+ window.dataLayer = window.dataLayer || [];
79
+ window.dataLayer.push({
80
+ "event": "openTab",
81
+ "tabTitle": button.textContent
82
+ });
83
+ });
84
+
85
+ });
86
+
87
+ // Make sure we dont loose existing summary functionality
88
+ summaries.forEach((summary, index) => {
89
+
90
+ // Maintain the focus on the summary element but visually highlight the tab button
91
+ summary.addEventListener("focus", (e) => {
92
+
93
+ buttons.forEach((button) => {
94
+
95
+ button.classList.remove('focus');
96
+ });
97
+ buttons[index].classList.add('focus');
98
+ });
99
+ summary.addEventListener("click", (e) => {
100
+
101
+ e.preventDefault();
102
+ buttons[index].click();
103
+ });
104
+ });
105
+
106
+ }
107
+
108
+ export const openFirstTab = function(tabsElement: Element){
109
+
110
+ let details = tabsElement.querySelectorAll(':scope > details');
111
+ let buttons = tabsElement.querySelectorAll(':scope > .tabs__links > button, .tabs__links > a');
112
+
113
+ if(tabsElement.shadowRoot)
114
+ buttons = tabsElement.shadowRoot.querySelectorAll('.tabs__links > button, .tabs__links > a');
115
+
116
+ if(location.hash && tabsElement.querySelector(`.tabs__links [href="${location.hash}"]`)){
117
+
118
+ tabsElement.querySelector(`[href="${location.hash}"]`).setAttribute('open',true);
119
+ tabsElement.querySelector(`details[id="${location.hash.replace('#','')}"]`).setAttribute('open',true);
120
+ }
121
+ else if(!tabsElement.querySelector(`details[open]`)) {
122
+
123
+ details[0].setAttribute('open',true);
124
+ buttons[0].setAttribute('aria-pressed',true);
125
+ }
126
+
127
+ }
128
+
129
+ const tabs = function(tabsElement: Element){
130
+
131
+ createTabsLinks(tabsElement);
132
+ setTabsEventHandlers(tabsElement);
133
+ openFirstTab(tabsElement);
134
+ }
135
+
136
+ export default tabs
@@ -2,13 +2,11 @@
2
2
  /**
3
3
  * Integrate YouTube videos as a way of hosting videos without the overhead and worry surrounding hosting vides. i.e. file sizes, performance and accessibility.
4
4
  */
5
- class youtubeVideo {
5
+ class youtubeVideo {
6
6
 
7
7
  /** @param {Element} embed dom element */
8
8
  constructor(embed){
9
9
 
10
- let createEmbed = this.createEmbed;
11
-
12
10
  // If the scripts is already loaded then lets just create the embed
13
11
  if(document.body.classList.contains('youtubeLoaded')){
14
12
  embed.addEventListener('click', function(e){
@@ -16,10 +14,10 @@
16
14
  // loop parent nodes from the target to the delegation node
17
15
  for (var target = e.target; target && target != this; target = target.parentNode) {
18
16
 
19
- if (target.matches('a:not([data-modal-youtube]')) {
17
+ if (target.matches('a')) {
20
18
 
21
19
  e.preventDefault();
22
- createEmbed(embed,target);
20
+ createEmbed(target);
23
21
  break;
24
22
  }
25
23
  }
@@ -33,9 +31,8 @@
33
31
  /**
34
32
  * Load the YouTube scripts before trying to create the embed
35
33
  * @param {HTMLElement} embed dom element
36
- * @param {Function} createEmbed function to create the embed after script loaded.
37
34
  */
38
- loadScripts(embed, createEmbed){
35
+ loadScripts(embed){
39
36
 
40
37
  return new Promise((resolve, reject) => {
41
38
 
@@ -52,18 +49,16 @@
52
49
 
53
50
  // script has loaded, you can now use it safely
54
51
  tag.onload = () => {
55
-
56
- embed.addEventListener('click', function(e){
52
+ embed.addEventListener('click', function(event){
53
+ console.log('click')
57
54
  // loop parent nodes from the target to the delegation node
58
- for (var target = e.target; target && target != this; target = target.parentNode) {
55
+
56
+ if (event && event.target instanceof HTMLElement && event.target.closest('a')) {
59
57
 
60
- if (target.matches('a:not([data-modal-youtube]')) {
61
-
62
- e.preventDefault();
63
- createEmbed(embed,target);
64
- break;
58
+ event.preventDefault();
59
+ createEmbed(event.target.closest('a'));
65
60
  }
66
- }
61
+
67
62
  }, false);
68
63
  }
69
64
 
@@ -80,67 +75,67 @@
80
75
  * Create the YouTube embed after the user has clicked on it.
81
76
  * @param {HTMLElement} embed dom element
82
77
  */
83
- createEmbed(embed,target){
78
+ }
84
79
 
85
- // If there is more than one video lets make sure there is only one playing at a time.
86
- if(typeof window.player != "undefined" && typeof window.player.pauseVideo == "function")
87
- window.player.pauseVideo();
80
+ export const createEmbed = function(target){
88
81
 
82
+ // If there is more than one video lets make sure there is only one playing at a time.
83
+ if(typeof window.player != "undefined" && typeof window.player.pauseVideo == "function")
84
+ window.player.pauseVideo();
89
85
 
90
- var video_id = target.getAttribute('data-id');
91
- var link_id = target.getAttribute('id')
92
86
 
93
- // create an id to pass t the script if one isn't present
94
- if(typeof link_id == 'undefined' || link_id == null){
87
+ var video_id = target.getAttribute('data-id');
88
+ var link_id = target.getAttribute('id')
95
89
 
96
- var randLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
97
- link_id = randLetter + Date.now();
98
- target.setAttribute('id',link_id);
99
- }
90
+ // create an id to pass t the script if one isn't present
91
+ if(typeof link_id == 'undefined' || link_id == null){
100
92
 
101
- // This function creates an <iframe> (and YouTube player) after the API code downloads.
102
- function onYouTubeIframeAPIReady() {
103
-
104
- window.player = new YT.Player(link_id, {
105
- height: '100%',
106
- width: '100%',
107
- videoId: video_id,
108
- playerVars: {
109
- 'modestbranding': 1,
110
- 'playsinline': 1,
111
- 'rel': 0,
112
- 'showinfo': 0
113
- },
114
- events: {
115
- 'onReady': onPlayerReady,
116
- 'onStateChange': onPlayerStateChange
117
- }
118
- });
93
+ var randLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
94
+ link_id = randLetter + Date.now();
95
+ target.setAttribute('id',link_id);
96
+ }
119
97
 
120
- }
121
- onYouTubeIframeAPIReady();
98
+ // This function creates an <iframe> (and YouTube player) after the API code downloads.
99
+ function onYouTubeIframeAPIReady() {
100
+
101
+ window.player = new YT.Player(link_id, {
102
+ height: '100%',
103
+ width: '100%',
104
+ videoId: video_id,
105
+ playerVars: {
106
+ 'modestbranding': 1,
107
+ 'playsinline': 1,
108
+ 'rel': 0,
109
+ 'showinfo': 0
110
+ },
111
+ events: {
112
+ 'onReady': onPlayerReady,
113
+ 'onStateChange': onPlayerStateChange
114
+ }
115
+ });
122
116
 
123
- // The API will call this function when the video player is ready.
124
- function onPlayerReady(event) {
125
- // Play the video straight away
126
- event.target.playVideo();
117
+ }
118
+ onYouTubeIframeAPIReady();
127
119
 
128
- }
120
+ // The API will call this function when the video player is ready.
121
+ function onPlayerReady(event) {
122
+ // Play the video straight away
123
+ event.target.playVideo();
129
124
 
130
- // The API calls this function when the player's state changes.
131
- // The function indicates that when playing a video (state=1)
132
- var done = false;
133
- function onPlayerStateChange(event) {
125
+ }
134
126
 
135
- if (event.data == YT.PlayerState.PLAYING && !done) {
127
+ // The API calls this function when the player's state changes.
128
+ // The function indicates that when playing a video (state=1)
129
+ var done = false;
130
+ function onPlayerStateChange(event) {
136
131
 
137
- var link = document.getElementById(link_id);
138
- link.classList.add('player-ready');
132
+ if (event.data == YT.PlayerState.PLAYING && !done) {
139
133
 
140
- done = true;
141
- }
134
+ var link = document.getElementById(link_id);
135
+ link.classList.add('player-ready');
136
+
137
+ done = true;
142
138
  }
143
139
  }
144
140
  }
145
-
146
141
  export default youtubeVideo
@@ -0,0 +1,29 @@
1
+ // @ts-nocheck
2
+ import '@testing-library/jest-dom'
3
+ import { filterTheList } from "../modules/filterlist";
4
+
5
+
6
+ const listHTML = `
7
+ <li class="lead text-primary pb-1">Olivia Anderson</li>
8
+ <li class="lead text-primary pb-1">Ethan Ramirez</li>
9
+ <li class="lead text-primary pb-1">Sophia Patel</li>
10
+ <li class="lead text-primary pb-1">Noah Jenkins</li>
11
+ <li class="lead text-primary pb-1">Ava Thompson</li>
12
+ <li class="lead text-primary pb-1">Lucas Myers</li>
13
+ <li class="lead text-primary pb-1">Mia Carter</li>
14
+ <li class="lead text-primary pb-1">Benjamin Lee</li>
15
+ `;
16
+
17
+ describe('addDataAttributes', () => {
18
+
19
+ let list = document.createElement('ul');
20
+ list.innerHTML = listHTML;
21
+
22
+ filterTheList(list, "Lucas");
23
+
24
+ test('should add a class of d-none to each item except the one containing Lucas Myers', () => {
25
+
26
+ expect(list.querySelectorAll('li:not(.d-none)').length).toEqual(1);
27
+ expect(list.querySelector('li:not(.d-none').textContent).toEqual('Lucas Myers');
28
+ });
29
+ });
@@ -0,0 +1,21 @@
1
+ // @ts-nocheck
2
+ import '@testing-library/jest-dom'
3
+ import createPaginationButttons from "../modules/pagination";
4
+
5
+ describe('createPaginationButttons', () => {
6
+
7
+ const pagination = document.createElement('div');
8
+
9
+ pagination.setAttribute('data-page',2);
10
+ pagination.setAttribute('data-pages',5);
11
+ pagination.setAttribute('data-show',15);
12
+ pagination.setAttribute('data-total',150);
13
+ pagination.setAttribute('data-increment',15);
14
+
15
+ createPaginationButttons(pagination, pagination);
16
+
17
+ test('should populate the pagination with links to each page', () => {
18
+
19
+ expect(pagination.querySelectorAll('a.page-link').length).toEqual(6);
20
+ });
21
+ });
@@ -0,0 +1,191 @@
1
+ // @ts-nocheck
2
+ import '@testing-library/jest-dom'
3
+ import * as tableModule from "../modules/table";
4
+ import puppeteer from 'puppeteer';
5
+ import "expect-puppeteer";
6
+
7
+ const basicTable = `<thead>
8
+ <tr>
9
+ <th>Heading 1</th>
10
+ <th>Heading 2</th>
11
+ <th>Heading 3</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody
15
+ <tr>
16
+ <td>Cell 1</td>
17
+ <td>Low</td>
18
+ <td>Cell 3</td>
19
+ </tr>
20
+ <tr>
21
+ <td>Cell 1</td>
22
+ <td>Low</td>
23
+ <td><a href="/link">View information</a></td>
24
+ </tr>
25
+ <tr>
26
+ <td>Different Cell 1</td>
27
+ <td>Medium</td>
28
+ <td><a href="/link">View information</a></td>
29
+ </tr>
30
+ <tr>
31
+ <td>Different Cell 1</td>
32
+ <td>High</td>
33
+ <td><a href="/link">View information</a></td>
34
+ </tr>
35
+ </tbody>`;
36
+
37
+ describe('addDataAttributes', () => {
38
+
39
+ const table = document.createElement('table');
40
+ table.innerHTML = basicTable;
41
+
42
+ tableModule.addDataAttributes(table);
43
+
44
+ test('should add data-label attribute to the table cells', () => {
45
+
46
+ expect(table.querySelector('tbody td').getAttribute('data-label')).toEqual('Heading 1');
47
+ expect(table.querySelector('tbody td:nth-child(2)').getAttribute('data-label')).toEqual('Heading 2');
48
+ });
49
+
50
+ test('should add data-content attribute to the table cells if the content matches a pre-defined list', () => {
51
+ expect(table.querySelector('tbody tr:nth-child(2) td:nth-child(2)').getAttribute('data-content')).toEqual('Low');
52
+ expect(table.querySelector('tbody tr:nth-child(3) td:nth-child(2)').getAttribute('data-content')).toEqual('Medium');
53
+ });
54
+
55
+ });
56
+
57
+ /* TODO: This unit test doesn't work as puppeteer seems to have an issue with query selector all
58
+ describe('getLargestLastColWidth', () => {
59
+
60
+ test('should return the width of the largest last column content', async() => {
61
+
62
+ const browser = await puppeteer.launch({});
63
+ try {
64
+ const page = await browser.newPage();
65
+ await page.exposeFunction("getLargestLastColWidth", tableModule.getLargestLastColWidth);
66
+ await page.setContent(`<table id="table">${basicTable}</table>`);
67
+ await page.waitForSelector('#table tr');
68
+
69
+ const largestWidth = await page.evaluate(`getLargestLastColWidth(document.querySelector("#table"))`);
70
+
71
+ //const links = await page.$$eval('#table', e=>getLargestLastColWidth(e))
72
+ console.log(await largestWidth)
73
+
74
+
75
+ } catch (e) {
76
+ console.error(e);
77
+ } finally {
78
+ await browser.close();
79
+ }
80
+
81
+
82
+ });
83
+
84
+ });
85
+ */
86
+
87
+ describe('createMobileButton', () => {
88
+
89
+ const table = document.createElement('table');
90
+ table.innerHTML = basicTable;
91
+
92
+ tableModule.createMobileButton(table);
93
+
94
+ test('should add a button to the first cell in a column', () => {
95
+
96
+ expect(table.querySelector('tbody td:nth-child(1) button').textContent).toEqual('Cell 1');
97
+ expect(table.querySelector('tbody td:nth-child(1) span').textContent).toEqual('Cell 1');
98
+ });
99
+ });
100
+
101
+ describe('createSearchDataList', () => {
102
+
103
+ const table = document.createElement('table');
104
+ table.innerHTML = basicTable;
105
+ const form = document.createElement('form');
106
+ form.innerHTML += `<div><input name="search" id="search" type="text" class="form-control" data-search="Heading 1"></div>`
107
+
108
+ tableModule.addDataAttributes(table);
109
+ tableModule.createSearchDataList(table, form);
110
+
111
+ test('should create a datalist populated by the defined columns in the data-search ', () => {
112
+
113
+ expect(form.querySelectorAll('datalist').length).toEqual(1);
114
+ expect(form.querySelectorAll('datalist option').length).toEqual(2);
115
+ expect(form.querySelector('datalist option:nth-child(1)').value).toEqual('Cell 1');
116
+ expect(form.querySelector('datalist option:nth-child(2)').value).toEqual('Different Cell 1');
117
+ });
118
+
119
+ test('should set the autocomplete attribute to off', () => {
120
+
121
+ expect(form.querySelectorAll('datalist').length).toEqual(1);
122
+ expect(form.querySelectorAll('datalist option').length).toEqual(2);
123
+ expect(form.querySelector('datalist option:nth-child(1)').value).toEqual('Cell 1');
124
+ expect(form.querySelector('input').getAttribute('autocomplete')).toEqual('off');
125
+ });
126
+
127
+ });
128
+
129
+ describe('sortTable', () => {
130
+
131
+ const table = document.createElement('table');
132
+ table.innerHTML = basicTable;
133
+ const form = document.createElement('form');
134
+ form.innerHTML += `<div><select type="select" name="sort" id="sort" class="form-select" data-sort=""><option value="-1">Sort by</option><option value="high" data-sort="Heading 2" data-order="High,Medium,Low" selected="selected">high to low</option></select></div>`
135
+ const savedTableBody = table.querySelector('tbody');
136
+
137
+ tableModule.addDataAttributes(table);
138
+ tableModule.sortTable(table, form, savedTableBody);
139
+
140
+ test('should sort the table from high to low', () => {
141
+
142
+ expect(table.querySelector('tbody tr:nth-child(1) td:nth-child(2)').textContent).toEqual('High');
143
+ expect(table.querySelector('tbody tr:nth-child(2) td:nth-child(2)').textContent).toEqual('Medium');
144
+ expect(table.querySelector('tbody tr:nth-child(3) td:nth-child(2)').textContent).toEqual('Low');
145
+ });
146
+
147
+
148
+ });
149
+
150
+ describe('filterTable', () => {
151
+
152
+ const table = document.createElement('table');
153
+ table.innerHTML = basicTable;
154
+ const form = document.createElement('form');
155
+ form.innerHTML += `<div><input type="text" name="filter" id="filter" data-filter="Heading 2" value="High" /></div>`;
156
+
157
+ tableModule.addDataAttributes(table);
158
+ tableModule.filterTable(table, form, document.createElement('div'));
159
+
160
+ test('should filter the table to only show high values', () => {
161
+
162
+ expect(table.querySelectorAll('tbody tr.filtered--matched').length).toEqual(1);
163
+ });
164
+ });
165
+
166
+ describe('populateDataQueries', () => {
167
+
168
+ const table = document.createElement('table');
169
+ table.innerHTML = basicTable;
170
+ const form = document.createElement('form');
171
+ form.innerHTML += `<div><span data-query="total"></span><span data-query="Heading 2 == Low"></span></div>`;
172
+
173
+ tableModule.addDataAttributes(table);
174
+ tableModule.populateDataQueries(table, form);
175
+
176
+ test('should populate elements with the data-query attribute with the result of the corresponding query', () => {
177
+
178
+
179
+ expect(form.querySelector('[data-query="total"]').textContent).toEqual('4');
180
+ expect(form.querySelector('[data-query="Heading 2 == Low"]').textContent).toEqual('2');
181
+ });
182
+ });
183
+
184
+ describe('formatCell', () => {
185
+
186
+ test('should format the text correctly', () => {
187
+
188
+ expect(tableModule.formatCell('date', '2023-05-15 12:10:45.000000')).toEqual('15 May 23');
189
+ expect(tableModule.formatCell('capitalise', 'low')).toEqual('Low');
190
+ });
191
+ });