@iamproperty/components 1.0.13 → 2.2.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.
- package/README.md +120 -12
- package/assets/.DS_Store +0 -0
- package/assets/favicons/android-chrome-192x192.png +0 -0
- package/assets/favicons/android-chrome-512x512.png +0 -0
- package/assets/favicons/apple-touch-icon.png +0 -0
- package/assets/favicons/favicon-16x16.png +0 -0
- package/assets/favicons/favicon-32x32.png +0 -0
- package/assets/favicons/favicon.ico +0 -0
- package/assets/fonts/qanelas-medium-webfont.woff +0 -0
- package/assets/fonts/qanelas-medium-webfont.woff2 +0 -0
- package/assets/fonts/qanelassoft-extrabold-webfont.woff +0 -0
- package/assets/fonts/qanelassoft-extrabold-webfont.woff2 +0 -0
- package/assets/img/.DS_Store +0 -0
- package/{src/assets → assets}/img/logo.png +0 -0
- package/assets/js/main.js +62 -0
- package/assets/js/modules/accordion.js +36 -0
- package/assets/js/modules/carousel.js +102 -0
- package/assets/js/modules/drawer.js +16 -0
- package/assets/js/modules/form.js +49 -0
- package/assets/js/modules/helpers.js +93 -0
- package/assets/js/modules/modal.js +72 -0
- package/assets/js/modules/nav.js +27 -0
- package/assets/js/modules/table.js +573 -0
- package/assets/js/modules/testimonial.js +83 -0
- package/assets/sass/.DS_Store +0 -0
- package/assets/sass/_components.scss +35 -0
- package/assets/sass/_corefiles.scss +58 -0
- package/assets/sass/_func.scss +9 -0
- package/assets/sass/_functions/functions.scss +95 -0
- package/assets/sass/_functions/mixins.scss +109 -0
- package/assets/sass/_functions/utilities.scss +238 -0
- package/assets/sass/_functions/variables.scss +411 -0
- package/assets/sass/components/accordion.scss +195 -0
- package/assets/sass/components/card.scss +168 -0
- package/assets/sass/components/cardDeck.scss +107 -0
- package/assets/sass/components/carousel.scss +265 -0
- package/assets/sass/components/charts.scss +562 -0
- package/assets/sass/components/drawer.scss +45 -0
- package/assets/sass/components/header.scss +57 -0
- package/assets/sass/components/modal.scss +133 -0
- package/assets/sass/components/nav.scss +619 -0
- package/assets/sass/components/property-searchbar.scss +138 -0
- package/assets/sass/components/snapshot.scss +69 -0
- package/assets/sass/components/tabs.scss +46 -0
- package/assets/sass/components/testimonial.scss +131 -0
- package/assets/sass/components/timeline.scss +93 -0
- package/assets/sass/core.scss +4 -0
- package/assets/sass/elements/buttons.scss +263 -0
- package/assets/sass/elements/container.scss +222 -0
- package/assets/sass/elements/forms.scss +128 -0
- package/assets/sass/elements/links.scss +95 -0
- package/assets/sass/elements/lists.scss +26 -0
- package/assets/sass/elements/media.scss +3 -0
- package/assets/sass/elements/tables.scss +247 -0
- package/assets/sass/elements/tooltips.scss +71 -0
- package/assets/sass/elements/type.scss +114 -0
- package/assets/sass/foundations/brand.scss +74 -0
- package/assets/sass/foundations/circles.scss +63 -0
- package/assets/sass/foundations/fonts.scss +17 -0
- package/assets/sass/foundations/icons.scss +46 -0
- package/assets/sass/foundations/reboot.scss +120 -0
- package/assets/sass/foundations/root.scss +45 -0
- package/assets/sass/main.scss +5 -0
- package/assets/svg/.DS_Store +0 -0
- package/assets/svg/flat/.DS_Store +0 -0
- package/assets/svg/flat/agreed.svg +1 -0
- package/assets/svg/flat/alert.svg +1 -0
- package/assets/svg/flat/asset-37.svg +1 -0
- package/assets/svg/flat/asset-73.svg +1 -0
- package/assets/svg/flat/asset-82.svg +1 -0
- package/assets/svg/flat/award.svg +1 -0
- package/assets/svg/flat/bath.svg +1 -0
- package/assets/svg/flat/bed.svg +1 -0
- package/assets/svg/flat/calculate.svg +1 -0
- package/assets/svg/flat/calendar.svg +1 -0
- package/assets/svg/flat/celebrate.svg +1 -0
- package/assets/svg/flat/chat-house.svg +1 -0
- package/assets/svg/flat/chat.svg +1 -0
- package/assets/svg/flat/circle.svg +1 -0
- package/assets/svg/flat/clean.svg +1 -0
- package/assets/svg/flat/clock.svg +1 -0
- package/assets/svg/flat/computer.svg +1 -0
- package/assets/svg/flat/down.svg +1 -0
- package/assets/svg/flat/edit.svg +1 -0
- package/assets/svg/flat/email.svg +1 -0
- package/assets/svg/flat/event.svg +1 -0
- package/assets/svg/flat/family.svg +1 -0
- package/assets/svg/flat/file.svg +1 -0
- package/assets/svg/flat/find.svg +1 -0
- package/assets/svg/flat/fireworks.svg +1 -0
- package/assets/svg/flat/fist-left.svg +1 -0
- package/assets/svg/flat/fist.svg +1 -0
- package/assets/svg/flat/folder.svg +1 -0
- package/assets/svg/flat/footprints.svg +1 -0
- package/assets/svg/flat/hand.svg +1 -0
- package/assets/svg/flat/hands.svg +1 -0
- package/assets/svg/flat/house-2.svg +1 -0
- package/assets/svg/flat/house.svg +1 -0
- package/assets/svg/flat/idea.svg +1 -0
- package/assets/svg/flat/judge-house.svg +1 -0
- package/assets/svg/flat/judge.svg +1 -0
- package/assets/svg/flat/keys-house.svg +1 -0
- package/assets/svg/flat/lock.svg +1 -0
- package/assets/svg/flat/mobile.svg +1 -0
- package/assets/svg/flat/money.svg +1 -0
- package/assets/svg/flat/monument.svg +1 -0
- package/assets/svg/flat/online-judgement.svg +1 -0
- package/assets/svg/flat/paint.svg +1 -0
- package/assets/svg/flat/person-2.svg +1 -0
- package/assets/svg/flat/person.svg +1 -0
- package/assets/svg/flat/phone.svg +1 -0
- package/assets/svg/flat/pin.svg +1 -0
- package/assets/svg/flat/pound.svg +1 -0
- package/assets/svg/flat/present.svg +1 -0
- package/assets/svg/flat/qualification.svg +1 -0
- package/assets/svg/flat/rocket.svg +1 -0
- package/assets/svg/flat/sale.svg +1 -0
- package/assets/svg/flat/save.svg +1 -0
- package/assets/svg/flat/scale.svg +1 -0
- package/assets/svg/flat/send.svg +1 -0
- package/assets/svg/flat/share.svg +1 -0
- package/assets/svg/flat/sofa.svg +1 -0
- package/assets/svg/flat/sold.svg +1 -0
- package/assets/svg/flat/star.svg +1 -0
- package/assets/svg/flat/stopwatch.svg +1 -0
- package/assets/svg/flat/task.svg +1 -0
- package/assets/svg/flat/telescope.svg +1 -0
- package/assets/svg/flat/thumb.svg +1 -0
- package/assets/svg/flat/time.svg +1 -0
- package/assets/svg/flat/up.svg +1 -0
- package/assets/svg/flat/valuation.svg +1 -0
- package/assets/svg/flat/value-house.svg +1 -0
- package/assets/svg/flat/warning.svg +1 -0
- package/assets/svg/flat/water.svg +1 -0
- package/assets/svg/icons.svg +51 -0
- package/assets/svg/illustrations/commuter1.svg +1 -0
- package/assets/svg/illustrations/commuter2.svg +1 -0
- package/assets/svg/illustrations/commuter3.svg +1 -0
- package/assets/svg/logo.svg +43 -0
- package/dist/components.common.js +8218 -390
- package/dist/components.common.js.map +1 -1
- package/dist/components.css +2 -1
- package/dist/components.css.map +1 -0
- package/dist/components.umd.js +8218 -390
- package/dist/components.umd.js.map +1 -1
- package/dist/components.umd.min.js +1 -1
- package/dist/components.umd.min.js.map +1 -1
- package/package.json +88 -57
- package/src/.DS_Store +0 -0
- package/src/components/Accordion/Accordion.vue +24 -0
- package/src/components/Accordion/AccordionItem.vue +43 -0
- package/src/components/Accordion/README.md +34 -0
- package/src/components/Banner/Banner.vue +38 -0
- package/src/components/Banner/README.md +24 -0
- package/src/components/Card/Card.vue +115 -0
- package/src/components/Card/README.md +24 -0
- package/src/components/CardDeck/CardDeck.vue +78 -0
- package/src/components/CardDeck/README.md +25 -0
- package/src/components/Carousel/Carousel.vue +86 -0
- package/src/components/Carousel/README.md +20 -0
- package/src/components/Chart/Chart.vue +246 -0
- package/src/components/Chart/README.md +18 -0
- package/src/components/Drawer/Drawer.vue +54 -0
- package/src/components/Drawer/README.md +23 -0
- package/src/components/Header/Header.vue +39 -0
- package/src/components/Header/README.md +28 -0
- package/src/components/Modal/Modal.vue +44 -0
- package/src/components/Modal/README.md +20 -0
- package/src/components/Nav/Nav.vue +129 -0
- package/src/components/Nav/README.md +23 -0
- package/src/components/PropertySearchbar/PropertySearchbar.vue +206 -0
- package/src/components/PropertySearchbar/README.md +26 -0
- package/src/components/Snapshot/README.md +21 -0
- package/src/components/Snapshot/Snapshot.vue +33 -0
- package/src/components/Tabs/README.md +27 -0
- package/src/components/Tabs/Tab.vue +17 -0
- package/src/components/Tabs/Tabs.vue +55 -0
- package/src/components/Testimonial/README.md +26 -0
- package/src/components/Testimonial/Testimonial.vue +61 -0
- package/src/components/Timeline/README.md +18 -0
- package/src/components/Timeline/Timeline.vue +25 -0
- package/src/elements/Input/Input.vue +236 -0
- package/src/elements/Input/README.md +18 -0
- package/src/elements/Table/README.md +55 -0
- package/src/elements/Table/Table.vue +112 -0
- package/src/foundations/Icon/Icon.vue +21 -0
- package/src/foundations/Icon/README.md +11 -0
- package/src/foundations/Logo/Logo.vue +39 -0
- package/src/foundations/Logo/README.md +20 -0
- package/src/helpers/strings.js +12 -0
- package/src/index.js +21 -6
- package/src/assets/css/default.css +0 -99
- package/src/assets/logo.png +0 -0
- package/src/assets/scss/_variables.scss +0 -13
- package/src/components/KeyFacts/KeyFact.vue +0 -45
- package/src/components/KeyFacts/KeyFactGroup.vue +0 -44
- package/src/components/KeyFacts/README.md +0 -23
- package/src/components/KeyInformation/KeyInformation.vue +0 -23
- package/src/components/KeyInformation/README.md +0 -32
- package/src/components/PropertyTaskIntro/PropertyTaskIntro.vue +0 -74
- package/src/components/PropertyTaskIntro/README.md +0 -27
- package/src/components/TaskTitle/README.md +0 -24
- package/src/components/TaskTitle/TaskTitle.vue +0 -68
- package/src/components/VendorTable/README.md +0 -63
- package/src/components/VendorTable/VendorTable.vue +0 -49
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
import { zeroPad, isNumeric } from "./helpers";
|
|
2
|
+
|
|
3
|
+
function table(tableElement) {
|
|
4
|
+
|
|
5
|
+
if(typeof tableElement != "object")
|
|
6
|
+
return false;
|
|
7
|
+
|
|
8
|
+
const thead = tableElement.querySelector('thead');
|
|
9
|
+
const tbody = tableElement.querySelector('tbody');
|
|
10
|
+
const storedData = tbody.cloneNode(true);
|
|
11
|
+
const sortedEvent = new Event('sorted');
|
|
12
|
+
const filteredEvent = new Event('filtered');
|
|
13
|
+
const randID = 'tabe_'+Math.random().toString(36).substr(2, 9); // Random to make sure IDs created are unique
|
|
14
|
+
let draggedRow;
|
|
15
|
+
|
|
16
|
+
tableElement.setAttribute('id',randID)
|
|
17
|
+
|
|
18
|
+
// #region Sortable
|
|
19
|
+
const sortTable = function(sortBy,sort){
|
|
20
|
+
|
|
21
|
+
// Create an array from the table rows, the index created is then used to sort the array
|
|
22
|
+
let tableArr = [];
|
|
23
|
+
Array.from(tbody.querySelectorAll('tr')).forEach((tableRow, index) => {
|
|
24
|
+
|
|
25
|
+
let rowIndex = tableRow.querySelector('td[data-label="'+sortBy+'"], th[data-label="'+sortBy+'"]').textContent;
|
|
26
|
+
|
|
27
|
+
if(isNumeric(rowIndex))
|
|
28
|
+
rowIndex = zeroPad(rowIndex,10)
|
|
29
|
+
|
|
30
|
+
const dataRow = {
|
|
31
|
+
index: rowIndex,
|
|
32
|
+
row: tableRow
|
|
33
|
+
}
|
|
34
|
+
tableArr.push(dataRow);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Sort array
|
|
38
|
+
tableArr.sort((a, b) => (a.index > b.index) ? 1 : -1)
|
|
39
|
+
|
|
40
|
+
// Reverse if descending
|
|
41
|
+
if(sort == "descending")
|
|
42
|
+
tableArr = tableArr.reverse();
|
|
43
|
+
|
|
44
|
+
// Create a string to return and populate the tbody
|
|
45
|
+
let strTbody = '';
|
|
46
|
+
tableArr.forEach((tableRow, index) => {
|
|
47
|
+
strTbody += tableRow.row.outerHTML;
|
|
48
|
+
});
|
|
49
|
+
tbody.innerHTML = strTbody;
|
|
50
|
+
|
|
51
|
+
// Dispatch the sortable event
|
|
52
|
+
tableElement.dispatchEvent(sortedEvent);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Declare event handlers
|
|
56
|
+
tableElement.addEventListener('click', function(e){
|
|
57
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
58
|
+
if (target.matches('[data-sortable]')) {
|
|
59
|
+
|
|
60
|
+
// Get current sort order
|
|
61
|
+
let sort = target.getAttribute('aria-sort') == "ascending" ? "descending" : "ascending";
|
|
62
|
+
|
|
63
|
+
// unset sort attributes
|
|
64
|
+
Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
|
|
65
|
+
col.setAttribute('aria-sort','none');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Set the sort order attribute
|
|
69
|
+
target.setAttribute('aria-sort', sort);
|
|
70
|
+
|
|
71
|
+
// Save the sort options on the table element so that it can be re-sorted later
|
|
72
|
+
tableElement.setAttribute('data-sort', sort);
|
|
73
|
+
tableElement.setAttribute('data-sortBy', target.textContent);
|
|
74
|
+
|
|
75
|
+
// Sort the table
|
|
76
|
+
sortTable(target.textContent, sort);
|
|
77
|
+
|
|
78
|
+
Array.from(tableElement.querySelectorAll('tr[draggable]')).forEach((tableRow, index) => {
|
|
79
|
+
|
|
80
|
+
tableRow.removeAttribute('draggable');
|
|
81
|
+
});
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, false);
|
|
86
|
+
|
|
87
|
+
// On page load check if the table should be pre-sorted, if so trigger a click
|
|
88
|
+
if(tableElement.getAttribute('data-sortBy')){
|
|
89
|
+
|
|
90
|
+
let sort = tableElement.getAttribute('data-sort') == "ascending" ? "descending" : "ascending";
|
|
91
|
+
|
|
92
|
+
Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
|
|
93
|
+
if(col.textContent == tableElement.getAttribute('data-sortBy')){
|
|
94
|
+
col.setAttribute('aria-sort',sort)
|
|
95
|
+
col.click();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// #endregion Sortable
|
|
101
|
+
|
|
102
|
+
// #region Filters
|
|
103
|
+
const createFilterForm = function(count){
|
|
104
|
+
|
|
105
|
+
// Create wrapper div
|
|
106
|
+
const form = document.createElement("div");
|
|
107
|
+
form.classList.add('table__filters');
|
|
108
|
+
form.classList.add('row');
|
|
109
|
+
form.classList.add('pt-1');
|
|
110
|
+
form.classList.add('pb-3');
|
|
111
|
+
|
|
112
|
+
// Create the filter options array
|
|
113
|
+
const filterColumns = Array.from(tableElement.querySelectorAll('th[data-filterable]'));
|
|
114
|
+
|
|
115
|
+
// Populate a list of searchable terms from the cells of the columns that could be used as a filter
|
|
116
|
+
let searchableTerms = {};
|
|
117
|
+
filterColumns.forEach((columnHeading, index) => {
|
|
118
|
+
Array.from(tableElement.querySelectorAll('td[data-label="'+columnHeading.textContent+'"]')).forEach((label, index) => {
|
|
119
|
+
|
|
120
|
+
searchableTerms[label.textContent] = label.textContent;
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Create the form
|
|
125
|
+
const filterTitle = filterColumns.length == 1 ? "Filter by "+filterColumns[0].textContent : "Filter"; // Update title if only one filter is chosen
|
|
126
|
+
const checkboxClass = filterColumns.length == 1 ? "d-none" : "d-sm-flex"; // Hide controls when only one filter is chosen
|
|
127
|
+
|
|
128
|
+
form.innerHTML = `<div class="col-sm-6 col-md-4 pb-3">
|
|
129
|
+
<div class="form-control__wrapper form-control-inline mb-0">
|
|
130
|
+
<label for="${randID}_filter" class="form-label">${filterTitle}:</label>
|
|
131
|
+
<input type="search" name="${randID}_filter" id="${randID}_filter" class="form-control form-control-sm" placeholder="" list="${randID}_list" />
|
|
132
|
+
</div>
|
|
133
|
+
<datalist id="${randID}_list">
|
|
134
|
+
${Object.keys(searchableTerms).map(term => `<option value="${term}"></option>`).join("")}
|
|
135
|
+
</datalist>
|
|
136
|
+
</div>
|
|
137
|
+
<div class="col-md-8 align-items-center pb-3 ${checkboxClass}">
|
|
138
|
+
${`<span class="pe-3 text-nowrap h5 mb-0">Filter by: </span>` + filterColumns.map(column => `<div class="form-check pe-3 mt-0 mb-0"><input class="form-check-input" type="checkbox" id="${randID}_${column.textContent.replace(' ','_').toLowerCase()}" checked="checked" /><label class="form-check-label text-nowrap" for="${randID}_${column.textContent.replace(' ','_').toLowerCase()}">${column.textContent}</label></div>`).join("")}
|
|
139
|
+
</div>`;
|
|
140
|
+
|
|
141
|
+
// Add before the actual table
|
|
142
|
+
tableElement.prepend(form)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const filterTable = function(searchTerm){
|
|
146
|
+
|
|
147
|
+
// Create an array of rows that match the search term
|
|
148
|
+
let tableArr = [];
|
|
149
|
+
Array.from(storedData.querySelectorAll('tr')).forEach((tableRow, index) => {
|
|
150
|
+
|
|
151
|
+
// We want one long search string per row including each filterable table cell
|
|
152
|
+
let rowSearchString = '';
|
|
153
|
+
Array.from(tableElement.querySelectorAll('[type="checkbox"]:checked + label')).forEach((label, index) => {
|
|
154
|
+
rowSearchString += tableRow.querySelector('td[data-label="'+label.textContent+'"]').textContent+' | ';
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Check if the table row search string contains the search term
|
|
158
|
+
if(rowSearchString.indexOf(searchTerm) >= 0){
|
|
159
|
+
|
|
160
|
+
const dataRow = { row: tableRow }
|
|
161
|
+
tableArr.push(dataRow);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Create a string to return and populate the tbody
|
|
166
|
+
let strTbody = '';
|
|
167
|
+
tableArr.forEach((tableRow, index) => {
|
|
168
|
+
strTbody += tableRow.row.outerHTML;
|
|
169
|
+
});
|
|
170
|
+
tbody.innerHTML = strTbody;
|
|
171
|
+
|
|
172
|
+
// Dispatch the filter event.
|
|
173
|
+
tableElement.dispatchEvent(filteredEvent);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const createFilterList = function(){
|
|
177
|
+
|
|
178
|
+
// Check which options are checked
|
|
179
|
+
let filterOptions = [];
|
|
180
|
+
Array.from(tableElement.querySelectorAll('[type="checkbox"]:checked + label')).forEach((label, index) => {
|
|
181
|
+
filterOptions.push(label.textContent);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Build up the list of searchable terms
|
|
185
|
+
let searchableTerms = [];
|
|
186
|
+
filterOptions.forEach((option, index) => {
|
|
187
|
+
Array.from(tableElement.querySelectorAll('td[data-label="'+option+'"]')).forEach((label, index) => {
|
|
188
|
+
searchableTerms[label.textContent] = label.textContent;
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Rebuild the list
|
|
193
|
+
let dataList = tableElement.querySelector('datalist');
|
|
194
|
+
dataList.innerHTML = Object.keys(searchableTerms).map(term => `<option value="${term}"></option>`).join("");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// On page load check if filters are needed
|
|
198
|
+
if(Array.from(tableElement.querySelectorAll('[data-filterable]')).length){
|
|
199
|
+
|
|
200
|
+
// Create the filter options
|
|
201
|
+
createFilterForm(tableElement,Array.from(tableElement.querySelectorAll('[data-filterable]')).length);
|
|
202
|
+
|
|
203
|
+
// Add event handlers for the filter options
|
|
204
|
+
tableElement.addEventListener('keyup', function(e){
|
|
205
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
206
|
+
if (target.matches('input[type="search"]')) {
|
|
207
|
+
|
|
208
|
+
const searchTerm = target.value;
|
|
209
|
+
filterTable(searchTerm)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
tableElement.addEventListener('change', function(e){
|
|
215
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
216
|
+
if (target.matches('input[type="search"]')) {
|
|
217
|
+
|
|
218
|
+
const searchTerm = target.value;
|
|
219
|
+
filterTable(searchTerm)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
tableElement.addEventListener('change', function(e){
|
|
225
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
226
|
+
if (target.matches('input[type="checkbox"]')) {
|
|
227
|
+
|
|
228
|
+
const searchTerm = tableElement.querySelector('input[type="search"]').value;
|
|
229
|
+
filterTable(searchTerm)
|
|
230
|
+
createFilterList()
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
// #endregion Filters
|
|
236
|
+
|
|
237
|
+
// #region Pagination
|
|
238
|
+
const paginateRows = function(show, page){
|
|
239
|
+
|
|
240
|
+
// Create some inline CSS to control what is viewed on the table, unline the filters we are just hiding the rable rows not removing them from the DOM.
|
|
241
|
+
let style = document.getElementById(randID+'_style');
|
|
242
|
+
|
|
243
|
+
if(style == null){
|
|
244
|
+
style = document.createElement("style");
|
|
245
|
+
style.setAttribute('id',randID+'_style')
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const startShowing = (show*(page-1))+1;
|
|
249
|
+
const stopShowing = show*(page);
|
|
250
|
+
|
|
251
|
+
style.innerHTML = `
|
|
252
|
+
#${randID} tbody tr {
|
|
253
|
+
display: none;
|
|
254
|
+
}
|
|
255
|
+
#${randID} tbody tr:nth-child(${startShowing}),
|
|
256
|
+
#${randID} tbody tr:nth-child(${startShowing}) ~ tr{
|
|
257
|
+
display: table-row;
|
|
258
|
+
}
|
|
259
|
+
#${randID} tbody tr:nth-child(${stopShowing}) ~ tr{
|
|
260
|
+
display: none;
|
|
261
|
+
}
|
|
262
|
+
`;
|
|
263
|
+
|
|
264
|
+
tableElement.append(style);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const createPaginationForm = function(show,page,totalRows){
|
|
268
|
+
|
|
269
|
+
const form = document.createElement("div");
|
|
270
|
+
form.classList.add('table__pagination');
|
|
271
|
+
form.classList.add('row');
|
|
272
|
+
form.classList.add('pt-3');
|
|
273
|
+
form.classList.add('pb-3');
|
|
274
|
+
|
|
275
|
+
// Create the form and create a container div to hold the pagination buttons
|
|
276
|
+
form.innerHTML = `<div class="col-6 col-sm-3 col-md-2 mb-3">
|
|
277
|
+
<div class="form-control__wrapper form-control-inline mb-0">
|
|
278
|
+
<label for="${randID}_showing" class="form-label">Showing:</label>
|
|
279
|
+
<input type="number" name="${randID}_showing" id="${randID}_showing" class="form-control form-control-sm" placeholder="" list="${randID}_pagination" value="${show}" min="1" max="${totalRows}" />
|
|
280
|
+
</div>
|
|
281
|
+
<datalist id="${randID}_pagination">
|
|
282
|
+
<option value="5">5</option>
|
|
283
|
+
${totalRows > 10 ? `<option value="10">10</option>` : ''}
|
|
284
|
+
${totalRows > 20 ? `<option value="20">20</option>` : ''}
|
|
285
|
+
<option value="${totalRows}">${totalRows}</option>
|
|
286
|
+
</datalist>
|
|
287
|
+
</div>
|
|
288
|
+
<div class="col-6 col-sm-2 col-md-2 d-flex align-items-center mb-3"><span class="label">per page</span></div>
|
|
289
|
+
<div class="col-sm-7 col-md-8 d-sm-flex justify-content-end align-items-center mb-3" id="${randID}_paginationBtns"></div>`;
|
|
290
|
+
|
|
291
|
+
// Add after the actual table
|
|
292
|
+
tableElement.append(form)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const createPaginationButttons = function(show,page,totalRows){
|
|
296
|
+
|
|
297
|
+
const paginationButtonsWrapper = document.getElementById(randID+'_paginationBtns')
|
|
298
|
+
|
|
299
|
+
if(paginationButtonsWrapper == null)
|
|
300
|
+
return false;
|
|
301
|
+
|
|
302
|
+
const numberPages = Math.ceil(totalRows / show)
|
|
303
|
+
|
|
304
|
+
if(numberPages == 1){ // Remore the buttons or dont display any if we dont need them
|
|
305
|
+
paginationButtonsWrapper.innerHTML = '';
|
|
306
|
+
}
|
|
307
|
+
else if(numberPages < 5){ // If less than 5 pages (which fits comfortably on mobile) we display buttons
|
|
308
|
+
|
|
309
|
+
let strButtons = '';
|
|
310
|
+
|
|
311
|
+
for (let i = 1; i <= numberPages; i++) {
|
|
312
|
+
|
|
313
|
+
if(i == page)
|
|
314
|
+
strButtons += `<li class="page-item active" aria-current="page"><span class="page-link">${i}</span></li>`;
|
|
315
|
+
else
|
|
316
|
+
strButtons += `<li class="page-item"><button class="page-link" data-page="${i}">${i}</button></li>`;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
paginationButtonsWrapper.innerHTML = `<span class="pe-2">Page: </span><ul class="pagination mb-0">
|
|
320
|
+
${page == 1 ? `<li class="page-item disabled"><span class="page-link">Previous</span></li>` : `<li class="page-item"><button class="page-link" data-page="${parseInt(page)-1}">Previous</button></li>`}
|
|
321
|
+
${strButtons}
|
|
322
|
+
${page == numberPages ? `<li class="page-item disabled"><span class="page-link">Next</span></li>` : `<li class="page-item"><button class="page-link" data-page="${parseInt(page)+1}">Next</button></li>`}
|
|
323
|
+
</ul>`;
|
|
324
|
+
|
|
325
|
+
}
|
|
326
|
+
else { // If more than 5 lets show a select field instead so that we dont have loads and loads of buttons
|
|
327
|
+
|
|
328
|
+
let strOptions = '';
|
|
329
|
+
|
|
330
|
+
for (let i = 1; i <= numberPages; i++) {
|
|
331
|
+
|
|
332
|
+
if(i == page)
|
|
333
|
+
strOptions += `<option value="${i}" selected>Page ${i}</option>`;
|
|
334
|
+
else
|
|
335
|
+
strOptions += `<option value="${i}">Page ${i}</option>`;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
paginationButtonsWrapper.innerHTML = `
|
|
339
|
+
<select class="form-select mb-3">
|
|
340
|
+
${strOptions}
|
|
341
|
+
</select>
|
|
342
|
+
`;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// On page load check if the table should be paginated
|
|
347
|
+
if(tableElement.getAttribute('data-show')){
|
|
348
|
+
|
|
349
|
+
const show = parseInt(tableElement.getAttribute('data-show'));
|
|
350
|
+
const page = parseInt(tableElement.getAttribute('data-page')) ? parseInt(tableElement.getAttribute('data-page')) : 1;
|
|
351
|
+
const totalRows = tableElement.querySelectorAll('tbody tr').length;
|
|
352
|
+
|
|
353
|
+
if(show < totalRows){
|
|
354
|
+
paginateRows(show,page);
|
|
355
|
+
createPaginationForm(show,page,totalRows);
|
|
356
|
+
createPaginationButttons(show,page,totalRows);
|
|
357
|
+
|
|
358
|
+
tableElement.addEventListener('change', function(e){
|
|
359
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
360
|
+
if (target.matches('.table__pagination input[type="number"]')) {
|
|
361
|
+
|
|
362
|
+
paginateRows(target.value,page);
|
|
363
|
+
createPaginationButttons(target.value,page,totalRows);
|
|
364
|
+
tableElement.setAttribute('data-show',target.value)
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
tableElement.addEventListener('click', function(e){
|
|
370
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
371
|
+
if (target.matches('.page-item:not(.active):not(.disabled) .page-link')) {
|
|
372
|
+
|
|
373
|
+
paginateRows(tableElement.getAttribute('data-show'),target.getAttribute('data-page'));
|
|
374
|
+
createPaginationButttons(tableElement.getAttribute('data-show'),target.getAttribute('data-page'),totalRows);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}, false);
|
|
378
|
+
|
|
379
|
+
tableElement.addEventListener('change', function(e){
|
|
380
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
381
|
+
if (target.matches('.table__pagination select')) {
|
|
382
|
+
|
|
383
|
+
paginateRows(tableElement.getAttribute('data-show'),target.value);
|
|
384
|
+
createPaginationButttons(tableElement.getAttribute('data-show'),target.value,totalRows);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
// #endregion Pagination
|
|
391
|
+
|
|
392
|
+
// #region Reorderable
|
|
393
|
+
// Set the row thats being dragged and copy the row
|
|
394
|
+
function setDraggedRow(e) {
|
|
395
|
+
e.dataTransfer.setData("text/plain", e.target.id);
|
|
396
|
+
draggedRow = e.target;
|
|
397
|
+
e.target.classList.add('tr--dragging');
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Create the order column and event handler for rows
|
|
401
|
+
const setReorderRows = function(){
|
|
402
|
+
|
|
403
|
+
Array.from(tbody.querySelectorAll('tr')).forEach((tableRow, index) => {
|
|
404
|
+
|
|
405
|
+
// Create column if not already created
|
|
406
|
+
if(tableRow.querySelector('[data-label="Order"]') == null){
|
|
407
|
+
|
|
408
|
+
const orderColumn = document.createElement('th');
|
|
409
|
+
orderColumn.innerHTML = index + 1;
|
|
410
|
+
orderColumn.setAttribute('data-label','Order');
|
|
411
|
+
tableRow.prepend(orderColumn);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Make draggable
|
|
415
|
+
tableRow.setAttribute('id',randID+'_row_'+(index+1));
|
|
416
|
+
tableRow.setAttribute('data-order',index+1);
|
|
417
|
+
tableRow.setAttribute('draggable','true');
|
|
418
|
+
tableRow.addEventListener("dragstart", setDraggedRow);
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if(tableElement.getAttribute('data-reorder')){
|
|
423
|
+
|
|
424
|
+
// Add column heading
|
|
425
|
+
const orderHeading = document.createElement('th');
|
|
426
|
+
orderHeading.innerHTML = 'Order';
|
|
427
|
+
orderHeading.classList.add('table-order-reset');
|
|
428
|
+
thead.querySelector('tr').prepend(orderHeading);
|
|
429
|
+
|
|
430
|
+
setReorderRows();
|
|
431
|
+
|
|
432
|
+
// Reset order button
|
|
433
|
+
tableElement.addEventListener('click', function(e){
|
|
434
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
435
|
+
if (target.matches('.table-order-reset')) {
|
|
436
|
+
|
|
437
|
+
// unset sort attributes
|
|
438
|
+
Array.from(tableElement.querySelectorAll('[data-sortable]')).forEach((col, index) => {
|
|
439
|
+
col.setAttribute('aria-sort','none');
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// Save the sort options on the table element so that it can be re-sorted later
|
|
443
|
+
tableElement.removeAttribute('data-sort');
|
|
444
|
+
tableElement.removeAttribute('data-sortBy');
|
|
445
|
+
|
|
446
|
+
// Sort the table
|
|
447
|
+
sortTable('Order', 'ascending');
|
|
448
|
+
|
|
449
|
+
Array.from(tableElement.querySelectorAll('tbody tr')).forEach((tableRow, index) => {
|
|
450
|
+
|
|
451
|
+
tableRow.setAttribute('draggable','true');
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}, false);
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
document.addEventListener("dragover", function( e ) {
|
|
461
|
+
// prevent default to allow drop
|
|
462
|
+
e.preventDefault();
|
|
463
|
+
}, false);
|
|
464
|
+
|
|
465
|
+
document.addEventListener("dragenter", function( e ) {
|
|
466
|
+
// prevent default to allow drop
|
|
467
|
+
e.preventDefault();
|
|
468
|
+
e.dataTransfer.dropEffect = "move";
|
|
469
|
+
|
|
470
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
471
|
+
if (target.matches('[data-reorder] tbody tr')) {
|
|
472
|
+
|
|
473
|
+
target.classList.add('tr--dropable')
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}, false);
|
|
477
|
+
|
|
478
|
+
document.addEventListener("dragleave", function( e ) {
|
|
479
|
+
// prevent default to allow drop
|
|
480
|
+
e.preventDefault();
|
|
481
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
482
|
+
if (target.matches('[data-reorder] tbody tr')) {
|
|
483
|
+
|
|
484
|
+
target.classList.remove('tr--dropable')
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}, false);
|
|
488
|
+
|
|
489
|
+
document.addEventListener("drop", function(e) {
|
|
490
|
+
|
|
491
|
+
e.preventDefault();
|
|
492
|
+
|
|
493
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
494
|
+
if (target.matches('[data-reorder] tbody tr')) {
|
|
495
|
+
|
|
496
|
+
if(target.parentNode != null && draggedRow.parentNode != null && target != draggedRow){
|
|
497
|
+
|
|
498
|
+
draggedRow.parentNode.removeChild( draggedRow );
|
|
499
|
+
|
|
500
|
+
if(draggedRow.getAttribute('data-order') > target.getAttribute('data-order'))
|
|
501
|
+
target.parentNode.insertBefore(draggedRow, target);
|
|
502
|
+
else
|
|
503
|
+
target.parentNode.insertBefore(draggedRow, target.nextElementSibling);
|
|
504
|
+
|
|
505
|
+
// Re label the rows
|
|
506
|
+
Array.from(tbody.querySelectorAll('tr')).forEach((tableRowOrder, index) => {
|
|
507
|
+
tableRowOrder.classList.remove('tr--dragging')
|
|
508
|
+
tableRowOrder.classList.remove('tr--dropable')
|
|
509
|
+
tableRowOrder.querySelector('th').innerHTML = index + 1;
|
|
510
|
+
tableRowOrder.setAttribute('data-order',index+1);
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}, false);
|
|
517
|
+
|
|
518
|
+
}
|
|
519
|
+
// #endregion Reorderable
|
|
520
|
+
|
|
521
|
+
// Watch for the filterable event and re-sort the tbody
|
|
522
|
+
tableElement.addEventListener('filtered', function (e) {
|
|
523
|
+
|
|
524
|
+
if(tableElement.getAttribute('data-sortBy') && tableElement.getAttribute('data-sort'))
|
|
525
|
+
sortTable(tableElement.getAttribute('data-sortBy'), tableElement.getAttribute('data-sort'));
|
|
526
|
+
|
|
527
|
+
if(tableElement.getAttribute('data-show')){
|
|
528
|
+
|
|
529
|
+
const show = parseInt(tableElement.getAttribute('data-show'));
|
|
530
|
+
const totalRows = tableElement.querySelectorAll('tbody tr').length;
|
|
531
|
+
const tablePagination = tableElement.querySelector('.table__pagination');
|
|
532
|
+
|
|
533
|
+
if(tablePagination != null)
|
|
534
|
+
tablePagination.remove();
|
|
535
|
+
|
|
536
|
+
if(show < totalRows){
|
|
537
|
+
|
|
538
|
+
paginateRows(show,1);
|
|
539
|
+
createPaginationForm(show,1,totalRows);
|
|
540
|
+
createPaginationButttons(show,1,totalRows);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if(tableElement.getAttribute('data-reorder')){
|
|
545
|
+
|
|
546
|
+
setReorderRows();
|
|
547
|
+
}
|
|
548
|
+
}, false);
|
|
549
|
+
|
|
550
|
+
tableElement.addEventListener('sorted', function (e) {
|
|
551
|
+
|
|
552
|
+
if(tableElement.getAttribute('data-reorder')){
|
|
553
|
+
|
|
554
|
+
setReorderRows();
|
|
555
|
+
}
|
|
556
|
+
}, false);
|
|
557
|
+
|
|
558
|
+
tableElement.addEventListener('populated', function (e) {
|
|
559
|
+
|
|
560
|
+
var tableFilter = tableElement.querySelector('.table__filters')
|
|
561
|
+
tableFilter.remove();
|
|
562
|
+
|
|
563
|
+
var tablePagination = tableElement.querySelector('.table__pagination')
|
|
564
|
+
tablePagination.remove();
|
|
565
|
+
|
|
566
|
+
var newTable = tableElement.cloneNode(true);
|
|
567
|
+
tableElement.parentNode.replaceChild(newTable, tableElement);
|
|
568
|
+
|
|
569
|
+
table(newTable);
|
|
570
|
+
}, false);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
export default table
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
function testimonial(testimonialElement) {
|
|
2
|
+
|
|
3
|
+
var scrollTimeout;
|
|
4
|
+
const imagesCarousel = testimonialElement.querySelector('.testimonial__images');
|
|
5
|
+
const itemCount = imagesCarousel.querySelectorAll('img').length;
|
|
6
|
+
|
|
7
|
+
// If we only have 1 item lets not bother doing anything else
|
|
8
|
+
if(itemCount == 1){
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
testimonialElement.classList.add('testimonial--multi')
|
|
13
|
+
|
|
14
|
+
// Set where the buttons go to
|
|
15
|
+
const setButtons = function(scrollTo){
|
|
16
|
+
|
|
17
|
+
const nextButton = testimonialElement.querySelector('.btn-next');
|
|
18
|
+
const prevButton = testimonialElement.querySelector('.btn-prev');
|
|
19
|
+
|
|
20
|
+
nextButton.setAttribute('data-go',scrollTo+1);
|
|
21
|
+
prevButton.setAttribute('data-go',scrollTo-1);
|
|
22
|
+
nextButton.removeAttribute('disabled')
|
|
23
|
+
prevButton.removeAttribute('disabled')
|
|
24
|
+
|
|
25
|
+
if(scrollTo == 1)
|
|
26
|
+
prevButton.setAttribute('disabled',true);
|
|
27
|
+
else if(scrollTo == itemCount)
|
|
28
|
+
nextButton.setAttribute('disabled',true);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// On scroll we need to make sure the buttons get corrected and the next testimonial is shown
|
|
32
|
+
imagesCarousel.addEventListener('scroll', function(e){
|
|
33
|
+
clearTimeout(scrollTimeout);
|
|
34
|
+
scrollTimeout = setTimeout(function(){
|
|
35
|
+
|
|
36
|
+
let scrollWidth = imagesCarousel.scrollWidth;
|
|
37
|
+
let scrollHeight = imagesCarousel.scrollHeight;
|
|
38
|
+
let scrollLeft = imagesCarousel.scrollLeft;
|
|
39
|
+
let scrollDown = imagesCarousel.scrollTop;
|
|
40
|
+
let scrollTo = Math.round((scrollLeft / scrollWidth) * itemCount) + 1;
|
|
41
|
+
|
|
42
|
+
// Change in scroll direction
|
|
43
|
+
if(scrollLeft == 0 && scrollDown != 0)
|
|
44
|
+
scrollTo = Math.round((scrollDown / scrollHeight) * itemCount) + 1;
|
|
45
|
+
|
|
46
|
+
testimonialElement.setAttribute('data-show',scrollTo)
|
|
47
|
+
setButtons(scrollTo);
|
|
48
|
+
}, 300);
|
|
49
|
+
|
|
50
|
+
}, false);
|
|
51
|
+
|
|
52
|
+
// when the buttons are used we need to make sure the carousel scrolls to the correct place
|
|
53
|
+
testimonialElement.addEventListener('click', function(e){
|
|
54
|
+
|
|
55
|
+
for (var target = e.target; target && target != this; target = target.parentNode) {
|
|
56
|
+
|
|
57
|
+
if (target.matches('[data-go]')) {
|
|
58
|
+
|
|
59
|
+
let scrollTo = parseInt(target.getAttribute('data-go'));
|
|
60
|
+
let scrollDown = 0;
|
|
61
|
+
let scrollLeft = 0
|
|
62
|
+
let scrollWidth = imagesCarousel.scrollWidth;
|
|
63
|
+
let scrollHeight = imagesCarousel.scrollHeight;
|
|
64
|
+
|
|
65
|
+
if(scrollWidth > scrollHeight)
|
|
66
|
+
scrollLeft = Math.floor(scrollWidth * ((scrollTo-1) / itemCount))
|
|
67
|
+
else
|
|
68
|
+
scrollDown = Math.floor(scrollHeight * ((scrollTo-1) / itemCount))
|
|
69
|
+
|
|
70
|
+
// Trigger the scroll
|
|
71
|
+
imagesCarousel.scroll({
|
|
72
|
+
top: scrollDown,
|
|
73
|
+
left: scrollLeft,
|
|
74
|
+
behavior: 'smooth'
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, false);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default testimonial
|
|
Binary file
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
//@import "../../node_modules/bootstrap/scss/nav";
|
|
3
|
+
//@import "../../node_modules/bootstrap/scss/navbar";
|
|
4
|
+
@import "components/nav.scss";
|
|
5
|
+
|
|
6
|
+
@import "components/header.scss";
|
|
7
|
+
@import "components/testimonial.scss";
|
|
8
|
+
@import "../../node_modules/bootstrap/scss/card";
|
|
9
|
+
@import "components/card.scss";
|
|
10
|
+
@import "components/cardDeck.scss";
|
|
11
|
+
//@import "../../node_modules/bootstrap/scss/accordion";
|
|
12
|
+
@import "components/accordion.scss";
|
|
13
|
+
//@import "../../node_modules/bootstrap/scss/breadcrumb";
|
|
14
|
+
@import "../../node_modules/bootstrap/scss/pagination";
|
|
15
|
+
@import "../../node_modules/bootstrap/scss/alert";
|
|
16
|
+
@import "../../node_modules/bootstrap/scss/progress";
|
|
17
|
+
@import "../../node_modules/bootstrap/scss/list-group";
|
|
18
|
+
@import "../../node_modules/bootstrap/scss/close";
|
|
19
|
+
@import "../../node_modules/bootstrap/scss/toasts";
|
|
20
|
+
@import "../../node_modules/bootstrap/scss/modal";
|
|
21
|
+
@import "../../node_modules/bootstrap/scss/tooltip";
|
|
22
|
+
@import "../../node_modules/bootstrap/scss/popover";
|
|
23
|
+
//@import "../../node_modules/bootstrap/scss/carousel";
|
|
24
|
+
@import "components/carousel.scss";
|
|
25
|
+
@import "../../node_modules/bootstrap/scss/spinners";
|
|
26
|
+
@import "../../node_modules/bootstrap/scss/offcanvas";
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@import "components/property-searchbar.scss";
|
|
30
|
+
@import "components/tabs.scss";
|
|
31
|
+
@import "components/modal.scss";
|
|
32
|
+
|
|
33
|
+
@import "components/charts.scss";
|
|
34
|
+
@import "components/timeline.scss";
|
|
35
|
+
@import "components/snapshot.scss";
|