@iamproperty/components 2.0.1 → 2.1.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 (59) hide show
  1. package/README.md +12 -2
  2. package/assets/.DS_Store +0 -0
  3. package/assets/css/core.min.css +1 -1
  4. package/assets/css/core.min.css.map +1 -1
  5. package/assets/css/style.min.css +1 -1
  6. package/assets/css/style.min.css.map +1 -1
  7. package/assets/img/.DS_Store +0 -0
  8. package/assets/js/main.js +4 -0
  9. package/assets/js/modules/accordion.js +13 -10
  10. package/assets/js/modules/modal.js +72 -0
  11. package/assets/js/scripts.bundle.js +98 -65
  12. package/assets/js/scripts.bundle.js.map +1 -1
  13. package/assets/js/scripts.bundle.min.js +2 -2
  14. package/assets/js/scripts.bundle.min.js.map +1 -1
  15. package/assets/sass/.DS_Store +0 -0
  16. package/assets/sass/_components.scss +4 -0
  17. package/assets/sass/_corefiles.scss +1 -0
  18. package/assets/sass/components/accordion.scss +79 -3
  19. package/assets/sass/components/charts.scss +562 -0
  20. package/assets/sass/components/modal.scss +78 -3
  21. package/assets/sass/components/snapshot.scss +69 -0
  22. package/assets/sass/components/timeline.scss +93 -0
  23. package/assets/sass/elements/buttons.scss +1 -1
  24. package/assets/sass/elements/tooltips.scss +71 -0
  25. package/assets/sass/foundations/reboot.scss +12 -0
  26. package/assets/svg/.DS_Store +0 -0
  27. package/assets/svg/flat/.DS_Store +0 -0
  28. package/dist/components.common.js +1318 -630
  29. package/dist/components.common.js.map +1 -1
  30. package/dist/components.css +1 -1
  31. package/dist/components.css.map +1 -1
  32. package/dist/components.umd.js +1318 -630
  33. package/dist/components.umd.js.map +1 -1
  34. package/dist/components.umd.min.js +1 -1
  35. package/dist/components.umd.min.js.map +1 -1
  36. package/package.json +34 -31
  37. package/src/.DS_Store +0 -0
  38. package/src/components/Accordion/Accordion.vue +0 -18
  39. package/src/components/Accordion/AccordionItem.vue +43 -0
  40. package/src/components/Accordion/README.md +21 -8
  41. package/src/components/Card/Card.vue +12 -12
  42. package/src/components/Card/README.md +7 -7
  43. package/src/components/CardDeck/CardDeck.vue +11 -11
  44. package/src/components/CardDeck/README.md +6 -6
  45. package/src/components/Carousel/Carousel.vue +10 -10
  46. package/src/components/Carousel/README.md +1 -1
  47. package/src/components/Chart/Chart.vue +246 -0
  48. package/src/components/Chart/README.md +18 -0
  49. package/src/components/Modal/Modal.vue +15 -4
  50. package/src/components/Modal/README.md +1 -0
  51. package/src/components/Nav/README.md +3 -3
  52. package/src/components/PropertySearchbar/PropertySearchbar.vue +13 -13
  53. package/src/components/Snapshot/README.md +21 -0
  54. package/src/components/Snapshot/Snapshot.vue +33 -0
  55. package/src/components/Timeline/README.md +18 -0
  56. package/src/components/Timeline/Timeline.vue +25 -0
  57. package/src/elements/Input/Input.vue +15 -15
  58. package/src/elements/Input/README.md +4 -4
  59. package/src/elements/Table/Table.vue +17 -3
@@ -0,0 +1,246 @@
1
+ <template>
2
+ <div class="container" ref="wrapper">
3
+ <slot></slot>
4
+ <figure class="chart__wrapper">
5
+ <figcaption v-html="caption"></figcaption>
6
+ <div :class="`chart__key chart__key--${type} h5`" role="presentation">
7
+ <div :key="index" v-for="(item,index) in fields" class="key">{{item.key}}</div>
8
+ </div>
9
+
10
+ <div :class="`chart chart--${type}`" ref="chart">
11
+
12
+ <div class="chart__yaxis" role="presentation">
13
+ <div :key="index" v-for="(point,index) in yaxis" :style="`--value: ${point.value};--percent:${((point.value-min)/(max-min))*100}%;`" class="axis__point">
14
+ <span>{{point.display}}</span>
15
+ </div>
16
+ </div>
17
+ <Table v-bind="$props">
18
+
19
+ <div class="chart__guidelines" role="presentation">
20
+ <div :key="index" v-for="(point,index) in yaxis" :data-value="point.value" :style="`--percent:${((point.value-min)/(max-min))*100}%;`" class="guideline">
21
+ </div>
22
+ </div>
23
+ <span v-html="drawLines()" class="lines" v-if="type == 'line'"></span>
24
+ </Table>
25
+ <div v-html="drawPie()" class="pies" v-if="type == 'pie'"></div>
26
+ </div>
27
+ </figure>
28
+ </div>
29
+ </template>
30
+
31
+ <style lang="scss">
32
+ @import "../../../assets/sass/_func.scss";
33
+ @import "../../../assets/sass/components/charts.scss";
34
+ </style>
35
+
36
+ <script>
37
+ import { ucfirst, unsnake } from '../../helpers/strings'
38
+ import Table from '@/elements/Table/Table.vue'
39
+
40
+ export default {
41
+ name: 'Tabs',
42
+ components: {
43
+ Table
44
+ },
45
+ props: {
46
+ type: {
47
+ type: String,
48
+ required: false,
49
+ default: 'bar'
50
+ },
51
+ caption: {
52
+ type: String,
53
+ required: false
54
+ },
55
+ max: {
56
+ type: Number,
57
+ required: true
58
+ },
59
+ min: {
60
+ type: Number,
61
+ required: false,
62
+ default: 0
63
+ },
64
+ yaxis: {
65
+ type: Array,
66
+ required: false
67
+ },
68
+ items: {
69
+ type: Array,
70
+ required: true
71
+ },
72
+ fields: {
73
+ type: Array,
74
+ required: true
75
+ }
76
+ },
77
+ computed: {
78
+ drawLines (){
79
+ return () => {
80
+
81
+ let lines = Array();
82
+ let spacer = 200/(Object.keys(this.items).length - 1);
83
+ const max = this.max - this.min;
84
+
85
+ // Creates the lines array from the fields array
86
+ this.fields.forEach((field, index) => {
87
+
88
+ if(index != 0){
89
+
90
+ lines[index-1] = '';
91
+ }
92
+ });
93
+
94
+ // populate the lines array from the items array
95
+ this.items.forEach((item, index) => {
96
+
97
+ Object.keys(item).forEach((key, subindex) => {
98
+
99
+ if(subindex != 0){
100
+
101
+ let value = item[key]
102
+
103
+ value = value.replace('£','');
104
+ value = value.replace('%','');
105
+ value = Number.parseFloat(value) - this.min;
106
+
107
+ const percent = (value/max) * 100;
108
+ let command = index == 0 ? 'M' : 'L';
109
+
110
+ lines[subindex-1] += `${command} ${spacer * index} ${100-percent} `;
111
+ }
112
+ });
113
+ });
114
+
115
+ // Create the line strings
116
+ let returnString = '';
117
+
118
+ lines.forEach((line, index) => {
119
+
120
+ returnString += `
121
+ <svg viewBox="0 0 200 100" class="line" preserveAspectRatio="none">
122
+ <path fill="none" d="${line}"></path>
123
+ </svg>`
124
+ });
125
+
126
+ return returnString;
127
+ }
128
+ },
129
+ drawPie (){
130
+ return () => {
131
+
132
+ let returnString = '';
133
+
134
+
135
+ this.items.forEach((item, index) => {
136
+
137
+ let paths = '';
138
+ let tooltips = '';
139
+
140
+ let cumulativePercent = 0;
141
+
142
+ function getCoordinatesForPercent(percent) {
143
+ const x = Math.cos(2 * Math.PI * percent);
144
+ const y = Math.sin(2 * Math.PI * percent);
145
+ return [x*100, y*100];
146
+ }
147
+
148
+ let total = 0;
149
+
150
+ let titleKey = Object.keys(item)[0]
151
+ let title = item[titleKey]
152
+
153
+ Object.keys(item).forEach((key, subindex) => {
154
+
155
+ if(subindex != 0){
156
+ let value = item[key]
157
+
158
+ value = value.replace('£','');
159
+ value = value.replace('%','');
160
+ value = Number.parseInt(value);
161
+
162
+ total += value;
163
+ }
164
+ });
165
+
166
+ Object.keys(item).forEach((key, subindex) => {
167
+
168
+
169
+ if(subindex != 0){
170
+
171
+ let value = item[key]
172
+
173
+ value = value.replace('£','');
174
+ value = value.replace('%','');
175
+ value = Number.parseInt(value);
176
+
177
+ let percent = value/total;
178
+
179
+ //lines[subindex-1] += `${command} ${spacer * index} ${100-percent} `;
180
+ const [startX, startY] = getCoordinatesForPercent(cumulativePercent);
181
+
182
+ // each slice starts where the last slice ended, so keep a cumulative percent
183
+ cumulativePercent += percent;
184
+
185
+ const [endX, endY] = getCoordinatesForPercent(cumulativePercent);
186
+
187
+ // if the slice is more than 50%, take the large arc (the long way around)
188
+ const largeArcFlag = percent > .5 ? 1 : 0;
189
+
190
+ // create an array and join it just for code readability
191
+ const pathData = [
192
+ `M ${startX} ${startY}`, // Move
193
+ `A 100 100 0 ${largeArcFlag} 1 ${endX} ${endY}`, // Arc
194
+ `L 0 0`, // Line
195
+ ].join(' ');
196
+
197
+ paths += `<path d="${pathData}"></path>`;
198
+ tooltips += `<foreignObject x="-70" y="-70" width="140" height="140" style="transform: rotate(90deg)"><div><span class="h5 mb-0">${ucfirst(unsnake(title))}<br/> ${ucfirst(unsnake(key))}<br/> ${item[key]}</span></div></foreignObject>`;
199
+ }
200
+ });
201
+
202
+ returnString += `<div class="pie"><svg viewBox="-105 -105 210 210" style="transform: rotate(-90deg)" preserveAspectRatio="none">${paths}<foreignObject x="-70" y="-70" width="140" height="140" style="transform: rotate(90deg)"><div><span class="h5 mb-0">${title}</span></div></foreignObject>${tooltips}</svg></div>`
203
+
204
+ });
205
+
206
+
207
+ return returnString;
208
+
209
+ }
210
+ }
211
+ },
212
+ mounted(){
213
+ this.$nextTick(function () {
214
+
215
+ // If the data gets updated we may need to recreate the tbody as it get detached when sorted in the table.js
216
+ let chart = this.$refs.chart;
217
+ const max = this.max - this.min;
218
+
219
+ Array.from(chart.querySelectorAll('tbody tr')).forEach((tr, index) => {
220
+
221
+ let group = tr.querySelector('td:first-child').innerHTML;
222
+
223
+ Array.from(tr.querySelectorAll('td[data-numeric]:not([data-numeric="0"]):not(:first-child)')).forEach((td, index) => {
224
+
225
+ const value = Number.parseFloat(td.getAttribute('data-numeric'));
226
+ let percent = ((value - this.min)/(max)) * 100;
227
+ const content = td.innerHTML;
228
+ const label = td.getAttribute('data-label');
229
+ let bottom = 0;
230
+
231
+ // If the value is negative the position below the 0 line
232
+ if(this.min < 0){
233
+ bottom = Math.abs((this.min)/(max)*100);
234
+ if(value < 0){
235
+ bottom = bottom - percent;
236
+ }
237
+ }
238
+ td.setAttribute("style",`--bottom:${bottom}%;--percent:${percent}%;`);
239
+
240
+ td.innerHTML = `<span data-group="${group}" data-label="${label}">${content}</span>`;
241
+ });
242
+ });
243
+ })
244
+ }
245
+ }
246
+ </script>
@@ -0,0 +1,18 @@
1
+ ### Usage
2
+
3
+ ```
4
+ <Chart :max="100" :min="0" :fields="fields" :items="items" :yaxis="yaxis"></Chart>
5
+ ```
6
+
7
+ ### Properties
8
+
9
+ **The charts props inherit the table props** - As charts are an extension of the tables.
10
+
11
+
12
+ | Option | Type | Default Value | Description |
13
+ | ------ | ---- | ------------- | ----------- |
14
+ | type | String | bar | Changes the type of chart shown (bar, line or pie) or by passing none a table is shown. |
15
+ | caption | String | - | Optional but recommended for accessibility concerns. Describes and summarizes the chart and the data inside it. |
16
+ | max | Number | - | Required numeric value to be used to work out the size/position of the chart elements. |
17
+ | min | Number | 0 | Optional (deaults to 0) numeric value to be used to work out the size/position of the chart elements. |
18
+ | yaxis | Array | - | Array of labels to be shown along the y-axis |
@@ -1,12 +1,14 @@
1
1
  <template>
2
- <div class="modal" :id="id">
3
- <a :href="`#${returnID?returnID:''}`"><span class="visually-hidden">Close</span></a>
2
+ <div class="modal" :id="id" role="dialog" modal="true" ref="modal">
3
+ <a :href="`#${returnid?returnid:''}`" tabindex="-1"><span class="visually-hidden">Close</span></a>
4
4
  <div class="modal__outer">
5
- <a :href="`#${returnID?returnID:''}`" class="btn btn-tertiary py-1 px-2"><span class="visually-hidden">Close</span>✕</a>
5
+ <a :href="`#${returnid?returnid:''}`" class="btn btn-tertiary py-1 px-2"><span class="visually-hidden">Close</span>✕</a>
6
6
  <div class="modal__inner">
7
7
  <slot></slot>
8
8
  </div>
9
9
  </div>
10
+ <button class="modal__dock--left btn btn-prev" tabindex="-1">Left</button>
11
+ <button class="modal__dock--right btn btn-next" tabindex="-1">Right</button>
10
12
  </div>
11
13
  </template>
12
14
 
@@ -16,6 +18,8 @@
16
18
  </style>
17
19
 
18
20
  <script>
21
+ import modal from '../../../assets/js/modules/modal.js'
22
+
19
23
  export default {
20
24
  name: 'Modal',
21
25
  props: {
@@ -23,11 +27,18 @@ export default {
23
27
  type: String,
24
28
  required: true
25
29
  },
26
- returnID: {
30
+ returnid: {
27
31
  type: String,
28
32
  default: 'close',
29
33
  required: false
30
34
  }
35
+ },
36
+ mounted(){
37
+
38
+ this.$nextTick(function () {
39
+
40
+ modal(this.$refs.modal);
41
+ })
31
42
  }
32
43
  }
33
44
  </script>
@@ -11,6 +11,7 @@
11
11
  | Option | Type | Default Value | Description |
12
12
  | ------ | ---- | ------------- | ----------- |
13
13
  | id | String | - | Required |
14
+ | returnid | String | close | Override the default id so that it will anchor to a specific location on the page. |
14
15
 
15
16
  ### Slots
16
17
 
@@ -9,9 +9,9 @@
9
9
  | Option | Type | Default Value | Description |
10
10
  | ------ | ---- | ------------- | ----------- |
11
11
  | logo | String | property | Update which logo is shown |
12
- | logoText | String | - | Optional logo text |
13
- | btnLink | String | - | Optional button can be added, used mainly for links relating to user accounts. |
14
- | btnText | String | - | Text used within the above button |
12
+ | logotext | String | - | Optional logo text |
13
+ | btnlink | String | - | Optional button can be added, used mainly for links relating to user accounts. |
14
+ | btntext | String | - | Text used within the above button |
15
15
 
16
16
 
17
17
  ### Slots
@@ -2,7 +2,7 @@
2
2
  <div class="container" ref="wrapper">
3
3
  <slot></slot>
4
4
  <div class="property-searchbar">
5
- <form class="row" :action="formAction" :method="formMethod">
5
+ <form class="row" :action="formaction" :method="formmethod">
6
6
  <fieldset class="col-12 col-md-3">
7
7
  <Input inputClass="input--locations" v-model="locationSet" label="Location" id="location" :options="locationsList()" required placeholder="i.e. Newcastle or NE1" @keyupEvent="locationKeyup(...arguments)" ref="search"></Input>
8
8
  <Input class="select--miles" label="Miles" id="miles" type="select" :options="distances"></Input>
@@ -10,19 +10,19 @@
10
10
  <fieldset class="col-12 col-md">
11
11
  <span class="form-label d-none d-md-block">Price range</span>
12
12
  <div class="row" data-input-range>
13
- <Input class="col-6" label="Minimum price" id="price-min" data-min="true" type="select" :options="priceMin"></Input>
14
- <Input class="col-6" label="Maximum price" id="price-max" data-max="true" type="select" :options="priceMax"></Input>
13
+ <Input class="col-6" label="Minimum price" id="price-min" data-min="true" type="select" :options="pricemin"></Input>
14
+ <Input class="col-6" label="Maximum price" id="price-max" data-max="true" type="select" :options="pricemax"></Input>
15
15
  </div>
16
16
  </fieldset>
17
17
  <fieldset class="col-12 col-md">
18
18
  <span class="form-label d-none d-md-block">Number of beds</span>
19
19
  <div class="row" data-input-range>
20
- <Input class="col-6" label="Minimum beds" id="beds-min" data-min="true" type="select" :options="bedsMin"></Input>
21
- <Input class="col-6" label="Maximum beds" id="beds-max" data-max="true" type="select" :options="bedsMax"></Input>
20
+ <Input class="col-6" label="Minimum beds" id="beds-min" data-min="true" type="select" :options="bedsmin"></Input>
21
+ <Input class="col-6" label="Maximum beds" id="beds-max" data-max="true" type="select" :options="bedsmax"></Input>
22
22
  </div>
23
23
  </fieldset>
24
24
  <fieldset class="col-12 col-md-2">
25
- <Input label="Property type" id="property-type" type="select" :options="propertyTypes"></Input>
25
+ <Input label="Property type" id="property-type" type="select" :options="propertytypes"></Input>
26
26
  </fieldset>
27
27
  <div class="col-12 col-md mw-md-fit-content d-flex property-searchbar__btn">
28
28
  <button class="btn w-100 me-0" type="submit" value="submit">Search</button>
@@ -48,11 +48,11 @@ export default {
48
48
  },
49
49
  name: 'PropertySearchbar',
50
50
  props: {
51
- formAction: {
51
+ formaction: {
52
52
  type: String,
53
53
  required: false
54
54
  },
55
- formMethod: {
55
+ formmethod: {
56
56
  type: String,
57
57
  required: false
58
58
  },
@@ -79,7 +79,7 @@ export default {
79
79
  ];
80
80
  }
81
81
  },
82
- priceMin: {
82
+ pricemin: {
83
83
  type: Array,
84
84
  required: false,
85
85
  default() {
@@ -94,7 +94,7 @@ export default {
94
94
  ];
95
95
  }
96
96
  },
97
- priceMax: {
97
+ pricemax: {
98
98
  type: Array,
99
99
  required: false,
100
100
  default() {
@@ -109,7 +109,7 @@ export default {
109
109
  ];
110
110
  }
111
111
  },
112
- bedsMin: {
112
+ bedsmin: {
113
113
  type: Array,
114
114
  required: false,
115
115
  default() {
@@ -125,7 +125,7 @@ export default {
125
125
  ];
126
126
  }
127
127
  },
128
- bedsMax: {
128
+ bedsmax: {
129
129
  type: Array,
130
130
  required: false,
131
131
  default() {
@@ -141,7 +141,7 @@ export default {
141
141
  ];
142
142
  }
143
143
  },
144
- propertyTypes: {
144
+ propertytypes: {
145
145
  type: Array,
146
146
  required: false,
147
147
  default() {
@@ -0,0 +1,21 @@
1
+ ### Usage
2
+
3
+ ```
4
+ <Snapshot :items="items"></Snapshot>
5
+ ```
6
+
7
+ ### Properties
8
+
9
+ | Option | Type | Default Value | Description |
10
+ | ------ | ---- | ------------- | ----------- |
11
+ | items | Array | - | Table row data passed |
12
+ | - item.title | String | - | Title of the snapshot figure |
13
+ | - item.bg | String | - | Theme colour to highlight the importance of the figure i.e. danger to indicate a high priority. |
14
+ | - item.number | String | - | The actual figure, recommended to be a single number but could be more i.e. 10 days.
15
+
16
+
17
+ ### Slots
18
+
19
+ | Option | Default Value | Description |
20
+ | ------ | ------------- | ----------- |
21
+ | default | - | Will display before the snapshot items |
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="container snapshot" ref="wrapper">
3
+ <slot></slot>
4
+ <div class="row">
5
+ <div class="col" v-for="(value,index) in items" :key="index">
6
+
7
+ <a :href="value.link" v-if="value.link">View {{value.title}}</a>
8
+ <div :class="`snapshot__item ${value.bg ? 'bg-'+value.bg : ''}`">
9
+ <span class="h6 snapshot__title">{{value.title}}</span>
10
+ <span class="stat">{{value.number}}</span>
11
+ </div>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </template>
16
+
17
+ <style lang="scss">
18
+ @import "../../../assets/sass/_func.scss";
19
+ @import "../../../assets/sass/components/snapshot.scss";
20
+ </style>
21
+
22
+ <script>
23
+
24
+ export default {
25
+ name: 'Snapshot',
26
+ props: {
27
+ items: {
28
+ type: Array,
29
+ required: true
30
+ },
31
+ }
32
+ }
33
+ </script>
@@ -0,0 +1,18 @@
1
+ <p class="note">The Timeline component represents an individual item within the timeline and not the full timeline itself. These Vue components need to be inside of a div with the class of 'timeline__container'.</p>
2
+
3
+ ### Usage
4
+
5
+ ```
6
+ <div class="timeline__container container">
7
+ <Timeline :image="require('../../assets/shutterstock_1229155495.webp')">
8
+ <h2>01 Search</h2>
9
+ <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
10
+ </Timeline>
11
+ </div>
12
+ ```
13
+
14
+ ### Properties
15
+
16
+ | Option | Type | Default Value | Description |
17
+ | ------ | ---- | ------------- | ----------- |
18
+ | image | String | - | Optional image url to display in the background |
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <div class="timeline">
3
+ <div class="timeline__content">
4
+ <slot></slot>
5
+ </div>
6
+ <img v-if="image" :src="image" alt="" />
7
+ </div>
8
+ </template>
9
+
10
+ <style lang="scss">
11
+ @import "../../../assets/sass/_func.scss";
12
+ @import "../../../assets/sass/components/timeline.scss";
13
+ </style>
14
+
15
+ <script>
16
+ export default {
17
+ name: 'Timeline',
18
+ props: {
19
+ image: {
20
+ type: String,
21
+ required: false
22
+ }
23
+ }
24
+ }
25
+ </script>
@@ -1,27 +1,27 @@
1
1
  <template>
2
2
  <div :class="wrapperClass()" ref="wrapper">
3
- <label v-if="needsLabel()" :class="`form-label${labelClass?` ${labelClass}`:''}`" :for="id" v-html="displayLabel()"></label>
3
+ <label v-if="needsLabel()" :class="`form-label${labelclass?` ${labelclass}`:''}`" :for="id" v-html="displayLabel()"></label>
4
4
 
5
5
  <!-- Standard input field -->
6
- <input v-if="isInput()" v-model="inputVal" :class="`form-control${size?` form-control-${size}`:``}${inputClass?` ${inputClass}`:``}`" :type="type" :name="name?name:id" :id="id" :pattern="needPattern()" :list="hasOptions()" v-bind="$attrs" v-on:keyup="inputKeyup" />
6
+ <input v-if="isInput()" v-model="inputVal" :class="`form-control${size?` form-control-${size}`:``}${inputclass?` ${inputclass}`:``}`" :type="type" :name="name?name:id" :id="id" :pattern="needPattern()" :list="hasOptions()" v-bind="$attrs" v-on:keyup="inputKeyup" />
7
7
 
8
8
  <!-- Textarea -->
9
- <textarea v-if="type=='textarea'" v-model="inputVal" :class="`form-control${size?` form-control-${size}`:``}${inputClass?` ${inputClass}`:``}`" :type="type" :name="name?name:id" :id="id" :pattern="needPattern()" v-bind="$attrs"></textarea>
9
+ <textarea v-if="type=='textarea'" v-model="inputVal" :class="`form-control${size?` form-control-${size}`:``}${inputclass?` ${inputclass}`:``}`" :type="type" :name="name?name:id" :id="id" :pattern="needPattern()" v-bind="$attrs"></textarea>
10
10
 
11
11
  <!-- Range -->
12
12
  <div class="input-group" v-if="type=='range'">
13
- <input v-model="inputVal" :class="`form-range${inputClass?` ${inputClass}`:``}`" :type="type" :name="name?name:id" :id="id" :pattern="needPattern()" :list="hasOptions()" v-bind="$attrs" oninput="this.nextElementSibling.value=this.value;" />
13
+ <input v-model="inputVal" :class="`form-range${inputclass?` ${inputclass}`:``}`" :type="type" :name="name?name:id" :id="id" :pattern="needPattern()" :list="hasOptions()" v-bind="$attrs" oninput="this.nextElementSibling.value=this.value;" />
14
14
  <output class="input-group-text border-0 col-2 col-sm-1 px-0">{{value}}</output>
15
15
  </div>
16
16
 
17
17
  <!-- Color picker -->
18
18
  <div class="input-group" v-if="type=='color'">
19
- <input v-model="inputVal" :class="`form-control form-control-color${inputClass?` ${inputClass}`:``}`" :type="type" :name="name?name:id" :id="id" :pattern="needPattern()" :list="hasOptions()" v-bind="$attrs" oninput="this.nextElementSibling.value=this.value;" />
19
+ <input v-model="inputVal" :class="`form-control form-control-color${inputclass?` ${inputclass}`:``}`" :type="type" :name="name?name:id" :id="id" :pattern="needPattern()" :list="hasOptions()" v-bind="$attrs" oninput="this.nextElementSibling.value=this.value;" />
20
20
  <output class="input-group-text flex-fill">{{value?vale:'#000000'}}</output>
21
21
  </div>
22
22
 
23
23
  <!-- Select/dropdown -->
24
- <select v-if="type=='select'" v-model="inputVal" :class="`form-select${size?` form-select-${size}`:``}${inputClass?` ${inputClass}`:``}`" :type="type" :name="id" :id="id" :pattern="needPattern()" v-bind="$attrs">
24
+ <select v-if="type=='select'" v-model="inputVal" :class="`form-select${size?` form-select-${size}`:``}${inputclass?` ${inputclass}`:``}`" :type="type" :name="id" :id="id" :pattern="needPattern()" v-bind="$attrs">
25
25
  <option v-for="(value,index) in options" :key="index" :value="value.value">{{value.display ? value.display : value.value}}</option>
26
26
  </select>
27
27
 
@@ -31,14 +31,14 @@
31
31
 
32
32
  <!-- Checkbox -->
33
33
  <input v-if="type=='checkbox'||type=='radio'" class="form-check-input" :type="type" :name="name?name:id" :id="id" v-bind="$attrs" />
34
- <label v-if="type=='checkbox'||type=='radio'" :class="`form-label form-check-label${labelClass?` ${labelClass}`:''}`" :for="id" v-html="label"></label>
34
+ <label v-if="type=='checkbox'||type=='radio'" :class="`form-label form-check-label${labelclass?` ${labelclass}`:''}`" :for="id" v-html="label"></label>
35
35
 
36
36
  <!-- Checkbox Button -->
37
- <input v-if="type=='checkbox-btn'||type=='radio-btn'" :class="`btn-check${inputClass?` ${inputClass}`:``}`" :type="type.replace('-btn','')" autocomplete="off" :name="name?name:id" :id="id" v-bind="$attrs" />
38
- <label v-if="type=='checkbox-btn'||type=='radio-btn'" :class="`btn${labelClass?` ${labelClass}`:''}`" :for="id" v-html="label" @click="clickEvent"></label>
37
+ <input v-if="type=='checkbox-btn'||type=='radio-btn'" :class="`btn-check${inputclass?` ${inputclass}`:``}`" :type="type.replace('-btn','')" autocomplete="off" :name="name?name:id" :id="id" v-bind="$attrs" />
38
+ <label v-if="type=='checkbox-btn'||type=='radio-btn'" :class="`btn${labelclass?` ${labelclass}`:''}`" :for="id" v-html="label" @click="clickEvent"></label>
39
39
 
40
40
  <!-- Error message -->
41
- <p v-if="errorMsg" class="invalid-feedback mb-0" v-html="errorMsg"></p>
41
+ <p v-if="errormsg" class="invalid-feedback mb-0" v-html="errormsg"></p>
42
42
  <slot></slot>
43
43
  </div>
44
44
  </template>
@@ -66,13 +66,13 @@ export default {
66
66
  },
67
67
  label: {
68
68
  type: String,
69
- required: true
69
+ required: false
70
70
  },
71
- labelClass: {
71
+ labelclass: {
72
72
  type: String,
73
73
  required: false
74
74
  },
75
- inputClass: {
75
+ inputclass: {
76
76
  type: String,
77
77
  required: false
78
78
  },
@@ -85,7 +85,7 @@ export default {
85
85
  type: String,
86
86
  required: false
87
87
  },
88
- errorMsg: {
88
+ errormsg: {
89
89
  type: String,
90
90
  required: false
91
91
  },
@@ -215,7 +215,7 @@ export default {
215
215
 
216
216
  let element = this.$refs.wrapper;
217
217
  // Remove unnecessary divs that may get in the way of our CSS sibling selectors working
218
- if(element.parentNode.classList.contains('form-check') || element.classList.length == 0){
218
+ if(element.parentNode && element.parentNode.classList.contains('form-check') || element.classList.length == 0){
219
219
 
220
220
  const fragment = document.createDocumentFragment();
221
221
  Array.from(element.childNodes).forEach(child => fragment.appendChild(child));
@@ -9,10 +9,10 @@
9
9
  | Option | Type | Default Value | Description |
10
10
  | ------ | ---- | ------------- | ----------- |
11
11
  | id | String | - | Required |
12
- | label | String | - | Required |
13
- | labelClass | String | - | Optional way of adding classes to the label, useful for assigning column class to label when usiong inline input fields. |
14
- | inputClass | String | - | Optional way of adding classes to the input field, useful for assigning column class to label when usiong inline input fields. |
12
+ | label | String | - | Not required but recommended |
13
+ | labelclass | String | - | Optional way of adding classes to the label, useful for assigning column class to label when usiong inline input fields. |
14
+ | inputclass | String | - | Optional way of adding classes to the input field, useful for assigning column class to label when usiong inline input fields. |
15
15
  | type | String | text | Assign different types to the input fields like number, email and date. |
16
16
  | size | String | - | Choose from either 'sm' and 'lg' |
17
- | errorMsg | String | - | Error message thats shown when the field fails form validation. |
17
+ | errormsg | String | - | Error message thats shown when the field fails form validation. |
18
18
  | options | Array | - | Used for the select type input field to populate the dropdown. Can also be used to create a datalist when used in conjuction of any other input type than select. |