@iamproperty/components 5.6.1-beta9 → 5.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 (92) hide show
  1. package/assets/css/components/address-lookup.css +1 -1
  2. package/assets/css/components/address-lookup.css.map +1 -1
  3. package/assets/css/components/carousel.css +1 -1
  4. package/assets/css/components/carousel.css.map +1 -1
  5. package/assets/css/components/fileupload.css +1 -1
  6. package/assets/css/components/fileupload.css.map +1 -1
  7. package/assets/css/components/pagination.css +1 -1
  8. package/assets/css/components/pagination.css.map +1 -1
  9. package/assets/css/components/tabs.css +1 -1
  10. package/assets/css/components/tabs.css.map +1 -1
  11. package/assets/css/core.min.css +1 -1
  12. package/assets/css/core.min.css.map +1 -1
  13. package/assets/css/style.min.css +1 -1
  14. package/assets/css/style.min.css.map +1 -1
  15. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  16. package/assets/js/components/actionbar/actionbar.component.min.js +3 -3
  17. package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
  18. package/assets/js/components/address-lookup/address-lookup.component.js +21 -10
  19. package/assets/js/components/address-lookup/address-lookup.component.min.js +6 -5
  20. package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -1
  21. package/assets/js/components/applied-filters/applied-filters.component.min.js +1 -1
  22. package/assets/js/components/card/card.component.js +39 -20
  23. package/assets/js/components/card/card.component.min.js +19 -19
  24. package/assets/js/components/card/card.component.min.js.map +1 -1
  25. package/assets/js/components/carousel/carousel.component.js +14 -1
  26. package/assets/js/components/carousel/carousel.component.min.js +5 -5
  27. package/assets/js/components/carousel/carousel.component.min.js.map +1 -1
  28. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +1 -1
  29. package/assets/js/components/fileupload/fileupload.component.js +16 -0
  30. package/assets/js/components/fileupload/fileupload.component.min.js +7 -5
  31. package/assets/js/components/fileupload/fileupload.component.min.js.map +1 -1
  32. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  33. package/assets/js/components/header/header.component.min.js +1 -1
  34. package/assets/js/components/inline-edit/inline-edit.component.js +2 -2
  35. package/assets/js/components/inline-edit/inline-edit.component.min.js +3 -3
  36. package/assets/js/components/inline-edit/inline-edit.component.min.js.map +1 -1
  37. package/assets/js/components/marketing/marketing.component.min.js +1 -1
  38. package/assets/js/components/multiselect/multiselect.component.min.js +1 -1
  39. package/assets/js/components/nav/nav.component.min.js +1 -1
  40. package/assets/js/components/notification/notification.component.min.js +1 -1
  41. package/assets/js/components/pagination/pagination.component.min.js +3 -3
  42. package/assets/js/components/search/search.component.min.js +1 -1
  43. package/assets/js/components/search/search.component.min.js.map +1 -1
  44. package/assets/js/components/slider/slider.component.min.js +1 -1
  45. package/assets/js/components/table/table.component.js +16 -1
  46. package/assets/js/components/table/table.component.min.js +4 -4
  47. package/assets/js/components/table/table.component.min.js.map +1 -1
  48. package/assets/js/components/tabs/tabs.component.js +3 -1
  49. package/assets/js/components/tabs/tabs.component.min.js +8 -6
  50. package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
  51. package/assets/js/dynamic.min.js +4 -4
  52. package/assets/js/dynamic.min.js.map +1 -1
  53. package/assets/js/modules/carousel.js +30 -8
  54. package/assets/js/modules/dialogs.js +6 -0
  55. package/assets/js/modules/fileupload.js +44 -12
  56. package/assets/js/modules/helpers.js +30 -0
  57. package/assets/js/modules/inputs.js +1 -1
  58. package/assets/js/modules/table.js +6 -1
  59. package/assets/js/modules/tabs.js +84 -1
  60. package/assets/js/scripts.bundle.js +34 -32
  61. package/assets/js/scripts.bundle.js.map +1 -1
  62. package/assets/js/scripts.bundle.min.js +2 -2
  63. package/assets/js/scripts.bundle.min.js.map +1 -1
  64. package/assets/sass/_components.scss +14 -0
  65. package/assets/sass/components/address-lookup.scss +4 -0
  66. package/assets/sass/components/carousel.scss +31 -7
  67. package/assets/sass/components/fileupload.scss +0 -10
  68. package/assets/sass/components/pagination.scss +11 -16
  69. package/assets/sass/components/tabs.scss +38 -3
  70. package/assets/sass/elements/admin-panel.scss +44 -6
  71. package/assets/sass/elements/dialog.scss +1 -1
  72. package/assets/sass/elements/forms.scss +3 -2
  73. package/assets/ts/components/address-lookup/address-lookup.component.ts +25 -11
  74. package/assets/ts/components/card/card.component.ts +49 -23
  75. package/assets/ts/components/carousel/carousel.component.ts +17 -1
  76. package/assets/ts/components/fileupload/fileupload.component.ts +26 -0
  77. package/assets/ts/components/inline-edit/inline-edit.component.ts +2 -2
  78. package/assets/ts/components/table/table.component.ts +24 -1
  79. package/assets/ts/components/tabs/tabs.component.ts +3 -1
  80. package/assets/ts/modules/carousel.ts +40 -9
  81. package/assets/ts/modules/dialogs.ts +8 -0
  82. package/assets/ts/modules/fileupload.ts +64 -20
  83. package/assets/ts/modules/helpers.ts +29 -0
  84. package/assets/ts/modules/inputs.ts +1 -1
  85. package/assets/ts/modules/table.ts +8 -2
  86. package/assets/ts/modules/tabs.ts +116 -1
  87. package/dist/components.es.js +199 -193
  88. package/dist/components.umd.js +78 -68
  89. package/dist/style.css +1 -1
  90. package/package.json +1 -1
  91. package/src/components/Card/Card.vue +1 -1
  92. package/src/components/Carousel/Carousel.vue +5 -1
@@ -80,4 +80,18 @@ iam-table {
80
80
  --row-bg: #000000;
81
81
  }
82
82
  }
83
+ }
84
+
85
+ iam-pagination {
86
+ --pagination-link-color: var(--colour-light);
87
+ --pagination-link-color-active: #E0E0E0;
88
+ }
89
+
90
+ iam-fileupload::part(file) {
91
+ @include dark-mode() {
92
+
93
+ background: var(--colour-canvas-2);
94
+ border-color: var(--colour-canvas-2);
95
+ color: var(--colour-body);
96
+ }
83
97
  }
@@ -7,6 +7,10 @@ input[name="postcode"] {
7
7
  border-color: var(--error-border,var(--colour-primary))!important;
8
8
  }
9
9
 
10
+ :is([name="postcode"]):is(:focus,.focus):not(:disabled) {
11
+ border-color: var(--colour-info)!important;
12
+ }
13
+
10
14
  div:has(input[name="postcode"]) .suffix {
11
15
 
12
16
  border-color: var(--error-border,var(--colour-primary))!important;
@@ -130,18 +130,39 @@
130
130
 
131
131
  // #region carousel controls/pips
132
132
  .carousel .carousel__controls {
133
-
134
- text-align: center;
135
- width: 10rem;
136
- max-height: 1rem;
137
133
  overflow: hidden;
138
134
  margin-inline: auto;
139
135
 
136
+ &:not(.thumbnails){
137
+ text-align: center;
138
+ max-width: 30rem;
139
+ }
140
+
141
+ &.thumbnails {
142
+ margin-block-start: 2rem;
143
+ }
144
+
140
145
  @include media-breakpoint-up(sm) {
141
146
  width: 100%;
142
147
  }
143
148
 
144
149
  button {
150
+ padding: 0;
151
+ margin: 0 0.2rem 0.2rem;
152
+ border: 3px solid var(--colour-canvas);
153
+ border-radius: 4px;
154
+
155
+ &.has-thumbnail {
156
+ height: 4.625rem;
157
+
158
+ img {
159
+ height: 100%;
160
+ width: auto;
161
+ }
162
+ }
163
+ }
164
+
165
+ button:not(.has-thumbnail) {
145
166
  width: 1rem;
146
167
  height: 1rem;
147
168
  min-height: 1rem;
@@ -149,10 +170,9 @@
149
170
  text-indent: -50rem;
150
171
  overflow: hidden;
151
172
  background: var(--colour-primary-theme);
152
- padding: 0;
153
173
  margin: 0 0.5rem 0.5rem 0.5rem;
154
174
  border: none;
155
-
175
+
156
176
  &:before {
157
177
  display: none;
158
178
  }
@@ -164,8 +184,12 @@
164
184
  }
165
185
 
166
186
  .carousel__controls > button[aria-current] {
187
+ --colour-active-thumbnail: var(--colour-info);
188
+ border-color: var(--colour-active-thumbnail);
167
189
 
168
- background: var(--colour-success);
190
+ &:not(.has-thumbnail) {
191
+ background: var(--colour-success);
192
+ }
169
193
  }
170
194
 
171
195
  // #endregion
@@ -50,16 +50,6 @@
50
50
  max-width: rem(400)!important;
51
51
  position: relative;
52
52
 
53
-
54
-
55
-
56
- @include dark-mode() {
57
-
58
- background: var(--colour-canvas-2);
59
- border-color: var(--colour-canvas-2);
60
- color: var(--colour-body);
61
- }
62
-
63
53
 
64
54
  @media (forced-colors: active) {
65
55
 
@@ -35,15 +35,18 @@
35
35
  padding-inline: 1rem;
36
36
 
37
37
  .select--minimal {
38
- --select-padding-left: rem(16);
39
- height: rem(52);
40
- line-height: rem(52);
38
+ height: calc(3.25rem - 1em);
39
+ line-height: calc(3.25rem - 1em);
41
40
  margin-left: rem(-16);
42
41
  font-weight: bold;
43
42
  }
44
43
 
45
44
  div:has(> select){
46
45
  margin-bottom: 0;
46
+
47
+ &:after {
48
+ top: 50%;
49
+ }
47
50
  }
48
51
  }
49
52
 
@@ -118,7 +121,7 @@
118
121
  display: none;
119
122
  background: none;
120
123
  padding-inline: 1rem;
121
-
124
+ color: var(--colour-body);
122
125
 
123
126
  @include container-up(sm) {
124
127
 
@@ -134,21 +137,13 @@
134
137
  }
135
138
 
136
139
  &:is(:hover,:focus):not(:disabled){
137
- background-color: var(--colour-light);
140
+ background-color: var(--pagination-link-color);
141
+ color: var(--colour-hover);
138
142
  }
139
143
 
140
144
  &:is(:active):not(:disabled){
141
- background-color: #E0E0E0;
142
- }
143
-
144
- @include dark-mode(){
145
- &:is(:hover,:focus):not(:disabled){
146
- background-color: var(--colour-canvas);
147
- }
148
-
149
- &:is(:active):not(:disabled){
150
- background-color: var(--colour-canvas);
151
- }
145
+ background-color: var(--pagination-link-color);
146
+ color: var(--colour-active);
152
147
  }
153
148
 
154
149
  &:disabled {
@@ -1,5 +1,32 @@
1
1
  @use "../_func" as *;
2
2
 
3
+ *:has(> iam-tabs){
4
+
5
+ container-type: inline-size;
6
+ }
7
+
8
+ iam-tabs {
9
+ details:not([open]) {
10
+ padding-bottom: 0;
11
+ }
12
+ }
13
+
14
+ iam-tabs::part(next-button) {
15
+ display: none;
16
+ }
17
+
18
+ iam-tabs.tabs--guided::part(next-button) {
19
+ @container (width > 62em) {
20
+ position: absolute;
21
+ top: rem(150);
22
+ right: 0;
23
+ display: block;
24
+ }
25
+ }
26
+ iam-tabs.tabs--guided::part(next-button):not(:hover) {
27
+ background: var(--colour-success);
28
+ }
29
+
3
30
  .tabs:not(.admin-panel) {
4
31
  position: relative;
5
32
 
@@ -12,11 +39,11 @@
12
39
  display: block;
13
40
  position: absolute;
14
41
  left: auto;
15
- right: -2.5rem;
42
+ right: -1.5rem;
16
43
  top: 0;
17
44
  bottom: 1px;
18
45
  width: 2.5rem;
19
- background: var(--tabs-gradient, linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,1)));
46
+ background: var(--tabs-gradient, linear-gradient(90deg, color(from var(--colour-canvas) a98-rgb r g b / 0), color(from var(--colour-canvas) a98-rgb r g b / 1)));
20
47
  z-index: 1000;
21
48
  pointer-events: none;
22
49
  }
@@ -44,6 +71,12 @@
44
71
  }
45
72
  }
46
73
 
74
+
75
+ .tabs__links {
76
+
77
+ scroll-snap-type: x mandatory;
78
+ }
79
+
47
80
  .tabs__links {
48
81
  padding-bottom: 3px;
49
82
  position: relative;
@@ -51,7 +84,7 @@
51
84
  flex-wrap: nowrap;
52
85
  width: auto;
53
86
  margin: 0 -1.5rem;
54
- overflow-y: hidden;
87
+ overflow-y: clip;
55
88
  overflow-x: auto;
56
89
 
57
90
  &::-webkit-scrollbar {
@@ -60,6 +93,8 @@
60
93
 
61
94
  .link {
62
95
  white-space: nowrap;
96
+ scroll-snap-align: start;
97
+ scroll-margin-left: var(--container-padding);
63
98
  }
64
99
 
65
100
  .link:not(.text-decoration-none):not(.btn) {
@@ -28,7 +28,8 @@
28
28
  display: none;
29
29
  }
30
30
 
31
- > :is(h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6):first-child {
31
+
32
+ > :is(h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6, .admin-panel__heading):first-child {
32
33
 
33
34
  --gradient-direction: -90deg!important;
34
35
  background-color:var(--colour-success);
@@ -37,17 +38,54 @@
37
38
  color: var(--colour-primary-theme);
38
39
  background-image: linear-gradient(var(--gradient-direction), var(--colour-info) 0, transparent 100%);
39
40
  }
40
-
41
- font-size: rem(18);
42
- line-height: rem(24);
43
- font-weight: bold;
44
- padding: rem(16) var(--padding-x);
41
+
45
42
  margin: calc(var(--padding-top) * -1) calc(var(--padding-x) * -1) var(--padding-top) calc(var(--padding-x) * -1);
46
43
  display: block;
47
44
  border-top-left-radius: rem(8);
48
45
  border-top-right-radius: rem(8);
49
46
  }
50
47
 
48
+ > :is(h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6):first-child,
49
+ .admin-panel__heading > :is(h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6) {
50
+ font-size: rem(18);
51
+ line-height: rem(24);
52
+ font-weight: bold;
53
+ padding: rem(16) var(--padding-x);
54
+ }
55
+
56
+ > :is(.admin-panel__heading):first-child {
57
+ display: flex;
58
+ flex-wrap: wrap;
59
+ gap: 1rem;
60
+ align-items: center;
61
+ padding: rem(16) var(--padding-x);
62
+
63
+ > :is(h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6) {
64
+ padding: 0;
65
+ margin-inline-end: auto;
66
+ }
67
+
68
+ .btn {
69
+ --btn-margin: 0;
70
+ }
71
+
72
+ .dialog__wrapper + .btn {
73
+ --btn-margin: 0.25rem;
74
+ margin-inline-end: 0;
75
+ }
76
+
77
+ @media (prefers-color-scheme: light) {
78
+ .btn-action,
79
+ .dialog__wrapper {
80
+ --colour-canvas-2: #FFFFFF;
81
+ --colour-heading: var(--colour-primary);
82
+ --colour-btn-action-hover-bg: var(--colour-light);
83
+ --colour-btn-hover: var(--colour-primary);
84
+ --colour-border: #D8D8D8;
85
+ }
86
+ }
87
+ }
88
+
51
89
  :is(iam-table, .iam-table) {
52
90
  margin: 0 0 rem(32) 0;
53
91
  padding: 0;
@@ -12,7 +12,7 @@ dialog[open] {
12
12
  --dialog-padding: #{rem(24)};
13
13
 
14
14
  --mh-padding-inline: var(--dialog-padding);
15
-
15
+ color: inherit;
16
16
  width: fit-content;
17
17
  height: fit-content;
18
18
  border: none;
@@ -83,7 +83,8 @@ $icon-tick: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' view
83
83
  }
84
84
 
85
85
  textarea {
86
- min-height: calc(var(--input-padding-block, #{rem(12)}) + var(--input-padding-block, #{rem(12)}) + (var(--input-lh, #{rem(20)}) * 3) + 4px)!important;
86
+ --textarea-height-scale: 3;
87
+ min-height: calc(var(--input-padding-block, #{rem(12)}) + var(--input-padding-block, #{rem(12)}) + (var(--input-lh, #{rem(20)}) * var(--textarea-height-scale)) + 4px)!important;
87
88
  }
88
89
  // #endregion
89
90
 
@@ -343,7 +344,7 @@ div:has(> label:first-child):has(> input):has(> :is(.form-control-inline,.input-
343
344
 
344
345
  // #region word counter
345
346
 
346
- input[maxlength] + span {
347
+ :is(input,textarea)[maxlength] + span {
347
348
 
348
349
  position: relative;
349
350
 
@@ -48,6 +48,7 @@ class iamAddressLookup extends HTMLElement {
48
48
  <div class="manual-address pb-2 js-hide">
49
49
  <slot></slot>
50
50
  <button class="btn btn-tertiary switch-to-lookup-btn" type="button">Use postcode lookup</button>
51
+ <slot name="after"></slot>
51
52
  </div>
52
53
  <div class="pre-filled pb-2 js-hide">
53
54
  <strong class="title text-primary d-block"></strong>
@@ -60,6 +61,7 @@ class iamAddressLookup extends HTMLElement {
60
61
 
61
62
  async connectedCallback() {
62
63
 
64
+ const component = this;
63
65
  const wrapper = this.shadowRoot.querySelector('.wrapper');
64
66
  const lookup = this.shadowRoot.querySelector('[name="postcode"]');
65
67
  const lookupWrapper = this.shadowRoot.querySelector('.postcode-lookup');
@@ -202,14 +204,19 @@ class iamAddressLookup extends HTMLElement {
202
204
  Object.keys(values).forEach((key, index) => {
203
205
 
204
206
  let value = values[key];
205
- if(this.querySelector(`[data-name="${key}"]`))
207
+ if(this.querySelector(`[data-name="${key}"]`) && value != '')
206
208
  this.querySelector(`[data-name="${key}"]`).value = value;
207
- else if(this.querySelector(`[name="${key}"]`))
209
+ else if(this.querySelector(`[data-name-alt="${key}"]`) && value != '')
210
+ this.querySelector(`[data-name-alt="${key}"]`).value = value;
211
+ else if(this.querySelector(`[name="${key}"]`) && value != '')
208
212
  this.querySelector(`[name="${key}"]`).value = value;
213
+
214
+ if(this.querySelector(`[data-name-2="${key}"]`))
215
+ this.querySelector(`[data-name-2="${key}"]`).value += ' '+value;
209
216
  });
210
217
 
211
218
  // Focus on first input
212
- this.querySelector('[data-name="address_1"]').focus();
219
+ this.querySelector('[name]').focus();
213
220
 
214
221
  Array.from(this.querySelectorAll('[data-required]')).forEach((input, index) => {
215
222
  input.setAttribute('required','true');
@@ -268,17 +275,24 @@ class iamAddressLookup extends HTMLElement {
268
275
  else {
269
276
  let values = JSON.stringify(address);
270
277
 
271
- let itemString = '';
278
+ if(component.hasAttribute('data-display-text')){
272
279
 
273
- for (const [key, value] of Object.entries(address)) {
274
-
275
- if(key == "address_number_name")
276
- itemString += `${value} `;
277
- else if(key != "postcode" && key != "address_title")
278
- itemString += `${value}${(/^-?\d+$/.test(value)?'':',')} `;
280
+ listString += `<option value="${address[component.getAttribute('data-display-text')]}, ${postcode}" data-values='${values}'></option>`;
281
+ }
282
+ else {
283
+
284
+ let itemString = '';
285
+ for (const [key, value] of Object.entries(address)) {
286
+
287
+ if(key == "address_number_name")
288
+ itemString += `${value} `;
289
+ else if(key != "postcode" && key != "address_title")
290
+ itemString += `${value}${(/^-?\d+$/.test(value)?'':',')} `;
291
+ }
292
+
293
+ listString += `<option value="${itemString}${postcode}" data-values='${values}'></option>`;
279
294
  }
280
295
 
281
- listString += `<option value="${itemString}${postcode}" data-values='${values}'></option>`;
282
296
  }
283
297
 
284
298
 
@@ -33,21 +33,7 @@ class iamCard extends HTMLElement {
33
33
  </style>
34
34
  <link rel="stylesheet" href="https://kit.fontawesome.com/26fdbf0179.css" crossorigin="anonymous">
35
35
  <div class="card ${classList}" tabindex="0" part="card">
36
- ${this.hasAttribute('data-image') || this.hasAttribute('data-record') ? `<div class="card__head">${this.hasAttribute('data-image') ? `<img src="${this.getAttribute('data-image')}" alt="" loading="lazy" />` : ``} <div class="card__badges"><slot name="badges"></slot></div></div>` : ''}
37
- <div class="card__body" part="body">
38
- ${!this.hasAttribute('data-image') && this.querySelector('[slot="badges"]') && this.querySelector('[slot="checkbox"]') ? `<div class="card__badges card__badges--inline"><slot name="badges"></slot></div>` : ''}
39
- ${!this.hasAttribute('data-image') && !this.hasAttribute('data-record') && this.querySelector('[slot="badges"]') ? `<div class="card__badges"><slot name="badges"></slot></div>` : ''}
40
- ${this.hasAttribute('data-illustration') ? `<div class="card__illustration"><img src="${this.getAttribute('data-illustration')}" alt="" loading="lazy" /></div>` : ''}
41
- <slot></slot>
42
- ${this.hasAttribute('data-total') ? `<div class="card__total">${this.getAttribute('data-total')}</div>` : ''}
43
- </div>
44
- ${this.hasAttribute('data-add-link') ? `<button class="btn btn-compact btn-secondary fa-plus">Add property</button>` : ''}
45
- <slot name="checkbox"></slot>
46
- <div class="card__footer" part="footer">
47
- <slot name="footer"></slot>
48
- <slot name="btns"></slot>
49
- ${this.hasAttribute('data-cta') ? `<span class="link d-inline-block pt-0 mb-0">${this.getAttribute('data-cta')}</span>` : ''}
50
- </div>
36
+ ${this.createCardConent()}
51
37
  </div>
52
38
  `;
53
39
  this.shadowRoot.appendChild(template.content.cloneNode(true));
@@ -57,16 +43,42 @@ class iamCard extends HTMLElement {
57
43
  document.head.insertAdjacentHTML('beforeend',`<style id="cardGlobal">${loadExtraCSS}</style>`);
58
44
  }
59
45
 
60
- connectedCallback() {
46
+ const createCardConent () {
47
+
48
+ return `${this.hasAttribute('data-image') || this.hasAttribute('data-record') ? `<div class="card__head">${this.hasAttribute('data-image') ? `<img src="${this.getAttribute('data-image')}" alt="" loading="lazy" />` : ``} <div class="card__badges"><slot name="badges"></slot></div></div>` : ''}
49
+ <div class="card__body" part="body">
50
+ ${!this.hasAttribute('data-image') && this.querySelector('[slot="badges"]') && this.querySelector('[slot="checkbox"]') ? `<div class="card__badges card__badges--inline"><slot name="badges"></slot></div>` : ''}
51
+ ${!this.hasAttribute('data-image') && !this.hasAttribute('data-record') && this.querySelector('[slot="badges"]') ? `<div class="card__badges"><slot name="badges"></slot></div>` : ''}
52
+ ${this.hasAttribute('data-illustration') ? `<div class="card__illustration"><img src="${this.getAttribute('data-illustration')}" alt="" loading="lazy" /></div>` : ''}
53
+ <slot></slot>
54
+ ${this.hasAttribute('data-total') ? `<div class="card__total">${this.getAttribute('data-total')}</div>` : ''}
55
+ </div>
56
+ ${this.hasAttribute('data-add-link') ? `<button class="btn btn-compact btn-secondary fa-plus">Add property</button>` : ''}
57
+ <slot name="checkbox"></slot>
58
+ <div class="card__footer" part="footer">
59
+ <slot name="footer"></slot>
60
+ <slot name="btns"></slot>
61
+ ${this.hasAttribute('data-cta') ? `<span class="link d-inline-block pt-0 mb-0">${this.getAttribute('data-cta')}</span>` : ''}
62
+ </div>`;
63
+ }
61
64
 
65
+ connectedCallback() {
62
66
  this.classList.add('loaded');
63
-
67
+
64
68
  // Mimic clicking the parent node so the focus and target events can be on the card
65
69
  const parentNode = this.parentNode.closest('a, button, label, router-link')
66
70
  const card = this.shadowRoot.querySelector('.card')
67
71
  const btnCompact = this.shadowRoot.querySelector('.btn-compact');
68
72
  const recordType = this.hasAttribute('data-record') ? this.getAttribute('data-record') : '';
69
73
 
74
+ /*
75
+ If the parentNode is actually just a div,
76
+ we don't want to look for anything or add events
77
+ */
78
+ if (!parentNode) {
79
+ return false;
80
+ }
81
+
70
82
  if(parentNode)
71
83
  parentNode.setAttribute('tabindex','-1');
72
84
 
@@ -182,7 +194,7 @@ class iamCard extends HTMLElement {
182
194
  }
183
195
 
184
196
  static get observedAttributes() {
185
- return ["data-total","class"];
197
+ return ["data-total","class","data-image"];
186
198
  }
187
199
 
188
200
  attributeChangedCallback(attrName, oldVal, newVal) {
@@ -193,12 +205,26 @@ class iamCard extends HTMLElement {
193
205
  break;
194
206
  }
195
207
  case "class": {
196
- let classList = this.classList.toString();
197
-
198
- if(this.querySelector('*:not(.badge):not(small):not(.btn) > [class*="fa-"]:not(.btn)'))
199
- classList += ' card--has-icon';
200
208
 
201
- this.shadowRoot.querySelector('.card').setAttribute('class',`card ${classList}`);
209
+ if(oldVal != newVal){
210
+ let classList = this.classList.toString();
211
+
212
+ if(this.querySelector('*:not(.badge):not(small):not(.btn) > [class*="fa-"]:not(.btn)'))
213
+ classList += ' card--has-icon';
214
+
215
+ this.shadowRoot.querySelector('.card').setAttribute('class',`card ${classList}`);
216
+
217
+ this.shadowRoot.querySelector('.card').innerHTML = this.createCardConent();
218
+ }
219
+
220
+ break;
221
+ }
222
+ case "data-image": {
223
+
224
+ if(oldVal != newVal){
225
+
226
+ this.shadowRoot.querySelector('.card').innerHTML = this.createCardConent();
227
+ }
202
228
  break;
203
229
  }
204
230
  }
@@ -49,6 +49,8 @@ class iamCarousel extends HTMLElement {
49
49
 
50
50
  const carouselElement = this.shadowRoot.querySelector('.carousel');
51
51
  const row = this.querySelector('.row');
52
+ const thumbnailImages = JSON.parse(this.dataset.thumbnails);
53
+
52
54
  const carouselControls = this.shadowRoot.querySelector('.carousel__controls');
53
55
 
54
56
  let itemCount = this.querySelectorAll(':scope > .row > .col').length
@@ -61,10 +63,24 @@ class iamCarousel extends HTMLElement {
61
63
  if(this.classList.contains('hide-controls'))
62
64
  carouselElement.classList.add('hide-controls');
63
65
 
66
+ if (thumbnailImages?.length) {
67
+ carouselControls.classList.add('thumbnails');
68
+ }
69
+
64
70
  // populate the pips
65
71
  let pips = "";
66
72
  for (let i = 1; i <= itemCount; i++) {
67
- pips += `<button class="control-${i}" data-slide="${i}" ${i == 1 ? "aria-current":""}>Slide ${i}</button>`;
73
+ let pipContent = null;
74
+ let pipClass = '';
75
+
76
+ if (thumbnailImages.length) {
77
+ pipClass = 'has-thumbnail';
78
+ pipContent = `<img src="${thumbnailImages[i - 1].src}" alt="Slide ${i}" height="148"/>`;
79
+ } else {
80
+ pipContent = `Slide ${i}`;
81
+ }
82
+
83
+ pips += `<button class="control-${i} ${pipClass}" data-slide="${i}" ${i == 1 ? "aria-current":""}>${pipContent}</button>`;
68
84
  }
69
85
  carouselControls.innerHTML = pips;
70
86
 
@@ -33,6 +33,8 @@ class iamFileupload extends HTMLElement {
33
33
  <hr/>
34
34
  <slot></slot>
35
35
  <div class="files" part="files"><slot name="files"></slot></div>
36
+ <span class="invalid-feedback ext">Some files did not match the accpeted extension type.</span>
37
+ <span class="invalid-feedback size">Some files Were too large to upload.</span>
36
38
  </div>
37
39
  `;
38
40
  this.shadowRoot.appendChild(template.content.cloneNode(true));
@@ -51,6 +53,30 @@ class iamFileupload extends HTMLElement {
51
53
 
52
54
  fileupload(this,wrapper);
53
55
  }
56
+
57
+
58
+ static get observedAttributes() {
59
+ return ["data-filename"];
60
+ }
61
+
62
+ attributeChangedCallback(attrName, oldVal, newVal) {
63
+
64
+ switch (attrName) {
65
+ case "data-filename": {
66
+ if(oldVal != newVal){
67
+
68
+ const filesWrapper = this.shadowRoot.querySelector('.files');
69
+
70
+ filesWrapper.innerHTML = `<span class="file">${newVal} <button data-file="${newVal}">Remove</button></span>`;
71
+
72
+ }
73
+ break;
74
+ }
75
+ }
76
+ }
77
+
78
+
79
+
54
80
  }
55
81
 
56
82
  export default iamFileupload;
@@ -26,8 +26,8 @@ class iamInlineEdit extends HTMLElement {
26
26
  <link rel="stylesheet" href="https://kit.fontawesome.com/26fdbf0179.css" crossorigin="anonymous">
27
27
 
28
28
  <slot></slot>
29
- <div class="btns">
30
- <button class="btn btn-action" id="save" part="save-btn"><i class="fa-regular fa-save m-0"></i> Save</button><button class="btn btn-action" id="cancel">Cancel</button>
29
+ <div class="btns" part="btns">
30
+ <button class="btn btn-action" id="save" part="save-btn"><i class="fa-regular fa-save m-0"></i> Save</button><button class="btn btn-action" id="cancel" part="cancel-btn">Cancel</button>
31
31
  </div>
32
32
  <div class="status pe-none" part="status">
33
33
  <span class="btn btn-action border-0 bg-transparent prevent-invert d-none" id="saving"><i class="fa-regular fa-spinner fa-spin me-1"></i> Saving...</span>
@@ -242,7 +242,10 @@ class iamTable extends HTMLElement {
242
242
 
243
243
 
244
244
  tableModule.makeTableFunctional(this.table, this.form, this.pagination, this);
245
- tableModule.filterTable(this.table, this.form,this);
245
+
246
+ if(!this.hasAttribute('data-no-submit'))
247
+ tableModule.filterTable(this.table, this.form,this);
248
+
246
249
  tableModule.populateDataQueries(this.table, this.form);
247
250
  }
248
251
 
@@ -256,6 +259,22 @@ class iamTable extends HTMLElement {
256
259
 
257
260
  });
258
261
 
262
+ // Push up the pagination events
263
+ this.pagination.addEventListener('update-show', (event) => {
264
+
265
+ let show = event.detail.show;
266
+
267
+ const updateEvent = new CustomEvent("update-show", { detail: { show: show } });
268
+ this.dispatchEvent(updateEvent);
269
+ });
270
+
271
+ this.pagination.addEventListener('update-page', (event) => {
272
+
273
+ let page = event.detail.page;
274
+
275
+ const updateEvent = new CustomEvent("update-page", { detail: { page: page } });
276
+ this.dispatchEvent(updateEvent);
277
+ });
259
278
  }
260
279
 
261
280
 
@@ -265,6 +284,10 @@ class iamTable extends HTMLElement {
265
284
 
266
285
  attributeChangedCallback(attrName, oldVal, newVal) {
267
286
 
287
+ if(this.hasAttribute('data-no-submit')){
288
+ return false;
289
+ }
290
+
268
291
  this.pagination = this.shadowRoot.querySelector('iam-pagination');
269
292
 
270
293
  switch (attrName) {