@abcagency/hc-ui-components 1.6.6 → 1.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/components/HireControlMap.js +43 -2
  2. package/dist/components/HireControlMap.js.map +1 -1
  3. package/dist/components/containers/accordions/filter-item-container.js +3 -1
  4. package/dist/components/containers/accordions/filter-item-container.js.map +1 -1
  5. package/dist/components/containers/filter/filter-item-container.js +29 -15
  6. package/dist/components/containers/filter/filter-item-container.js.map +1 -1
  7. package/dist/components/modules/accordions/filterItem.js +8 -3
  8. package/dist/components/modules/accordions/filterItem.js.map +1 -1
  9. package/dist/components/modules/filter/index.js +87 -20
  10. package/dist/components/modules/filter/index.js.map +1 -1
  11. package/dist/components/modules/filter/item.js +8 -3
  12. package/dist/components/modules/filter/item.js.map +1 -1
  13. package/dist/components/modules/filter/search.js +6 -1
  14. package/dist/components/modules/filter/search.js.map +1 -1
  15. package/dist/contexts/mapListContext.js +48 -3
  16. package/dist/contexts/mapListContext.js.map +1 -1
  17. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +51 -1
  18. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
  19. package/dist/styles/index.css +1 -1
  20. package/dist/types/util/filterUtil.d.ts +9 -3
  21. package/dist/util/filterUtil.js +77 -14
  22. package/dist/util/filterUtil.js.map +1 -1
  23. package/dist/util/twMerge.js +9 -0
  24. package/dist/util/twMerge.js.map +1 -0
  25. package/package.json +1 -1
  26. package/src/components/HireControlMap.js +48 -2
  27. package/src/components/containers/accordions/filter-item-container.js +1 -1
  28. package/src/components/containers/filter/filter-item-container.js +27 -14
  29. package/src/components/modules/accordions/filterItem.js +16 -3
  30. package/src/components/modules/filter/index.js +114 -41
  31. package/src/components/modules/filter/item.js +15 -3
  32. package/src/components/modules/filter/search.js +7 -1
  33. package/src/contexts/mapListContext.tsx +96 -3
  34. package/src/util/filterUtil.js +63 -17
  35. package/src/util/twMerge.js +6 -0
@@ -4,10 +4,10 @@ import { isAlgoliaAvailable, filterListingsByAlgoliaSearch } from '~/util/algoli
4
4
 
5
5
  import Fuse from 'fuse.js';
6
6
 
7
- export const getFilterOptions = (listings, filteredListings, field, excludeZeroCount = null) => {
7
+ export const getFilterOptions = (listings, filteredListings, field, excludeZeroCount = false, sortAlphabetically = false) => {
8
8
  const options = new Set();
9
9
  listings.forEach(listing => {
10
- if (listing.fields[field]) {
10
+ if (listing.fields && listing.fields[field]) {
11
11
  options.add(listing.fields[field]);
12
12
  }
13
13
  });
@@ -18,22 +18,32 @@ export const getFilterOptions = (listings, filteredListings, field, excludeZeroC
18
18
  });
19
19
 
20
20
  filteredListings.forEach(listing => {
21
+ if (!listing.fields) return;
21
22
  const value = listing.fields[field];
22
- if (value && optionCounts.hasOwnProperty(value)) {
23
+ if (value && Object.prototype.hasOwnProperty.call(optionCounts, value)) {
23
24
  optionCounts[value] += 1;
24
25
  }
25
26
  });
26
27
 
27
- return Array.from(options)
28
- .sort()
28
+ let result = Array.from(options)
29
+ .filter(option => option != null && option !== '') // Filter out null/empty values
29
30
  .map(option => ({
30
31
  name: option,
31
32
  count: optionCounts[option] || 0
32
33
  }))
33
34
  .filter(option => !(excludeZeroCount === true && option.count === 0));
35
+
36
+ // Sort alphabetically or by count
37
+ if (sortAlphabetically) {
38
+ result.sort((a, b) => a.name.localeCompare(b.name));
39
+ } else {
40
+ result.sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
41
+ }
42
+
43
+ return result;
34
44
  };
35
45
 
36
- export const getSpecialFeatureOptions = (listings, filteredListings, siteConfig, favorites) => {
46
+ export const getSpecialFeatureOptions = (listings, filteredListings, siteConfig, favorites, filterConfig = {}) => {
37
47
  const specialFeatures = siteConfig.specialFeatures;
38
48
  const featureCounts = Object.keys(specialFeatures).sort().reduce((acc, key) => {
39
49
  acc[specialFeatures[key]] = 0;
@@ -48,17 +58,28 @@ export const getSpecialFeatureOptions = (listings, filteredListings, siteConfig,
48
58
  });
49
59
  });
50
60
 
51
- const specialFeatureOptions = Object.entries(featureCounts).map(([name, count]) => ({
61
+ let specialFeatureOptions = Object.entries(featureCounts).map(([name, count]) => ({
52
62
  name,
53
63
  count
54
64
  }));
55
65
 
66
+ // Update favorite count
56
67
  for (let option of specialFeatureOptions) {
57
68
  if (option.name === 'Favorite') {
58
69
  option.count = filteredListings.filter(x => favorites.includes(x.id)).length;
59
70
  }
60
71
  }
61
72
 
73
+ // Hide favorites if filterConfig.showFavorites is false
74
+ if (filterConfig.showFavorites === false) {
75
+ specialFeatureOptions = specialFeatureOptions.filter(option => option.name !== 'Favorite');
76
+ }
77
+
78
+ // Hide zero results if filterConfig.hideZeroResults is true
79
+ if (filterConfig.hideZeroResults === true) {
80
+ specialFeatureOptions = specialFeatureOptions.filter(option => option.count > 0);
81
+ }
82
+
62
83
  return specialFeatureOptions;
63
84
  };
64
85
 
@@ -76,9 +97,19 @@ export const generateFilterOptions = (
76
97
  filterOptions,
77
98
  parentField,
78
99
  favorites,
79
- selectedFilters
100
+ selectedFilters,
101
+ filterConfig = {
102
+ hideZeroResults: false,
103
+ dynamicCounts: true,
104
+ showFavorites: true,
105
+ collapsedByDefault: false,
106
+ sortAlphabetically: false
107
+ }
80
108
  ) => {
81
109
  if (allListings.length > 0) {
110
+ // Determine which listings to use for counts based on dynamicCounts setting
111
+ const countListings = filterConfig.dynamicCounts ? filteredListings : allListings;
112
+
82
113
  const dynamicFilters = siteConfig.fieldFiltersShown.map(fieldName => {
83
114
  if (fieldName === parentField && filterOptions?.filters) {
84
115
  return filterOptions.filters.find(filter => filter.id === fieldName);
@@ -87,31 +118,31 @@ export const generateFilterOptions = (
87
118
  return {
88
119
  id: fieldName,
89
120
  title: siteConfig.fieldNames[fieldName],
90
- items: getFilterOptions(allListings, allListings, fieldName)
121
+ items: getFilterOptions(allListings, countListings, fieldName, filterConfig.hideZeroResults, filterConfig.sortAlphabetically)
91
122
  };
92
123
  }
93
124
  if(fieldName == 'subCategory' && selectedFilters.category){
94
125
  const categoryKeys = Object.keys(selectedFilters.category);
95
- const filteredListings = allListings.filter(
126
+ const filteredByCategory = allListings.filter(
96
127
  x => categoryKeys.includes(x.fields?.category)
97
128
  );
98
129
  return {
99
130
  id: fieldName,
100
131
  title: siteConfig.fieldNames[fieldName],
101
- items: getFilterOptions(allListings, filteredListings, fieldName, false)
132
+ items: getFilterOptions(allListings, filteredByCategory, fieldName, filterConfig.hideZeroResults, filterConfig.sortAlphabetically)
102
133
  };
103
134
  }
104
135
  if (fieldName == "specialFeatures") {
105
136
  return {
106
137
  id: fieldName,
107
138
  title: siteConfig.fieldNames[fieldName],
108
- items: getSpecialFeatureOptions(allListings, filteredListings, siteConfig, favorites).sort()
139
+ items: getSpecialFeatureOptions(allListings, countListings, siteConfig, favorites, filterConfig).sort()
109
140
  };
110
141
  }
111
142
  return {
112
143
  id: fieldName,
113
144
  title: siteConfig.fieldNames[fieldName],
114
- items: getFilterOptions(allListings, filteredListings, fieldName)
145
+ items: getFilterOptions(allListings, countListings, fieldName, filterConfig.hideZeroResults, filterConfig.sortAlphabetically)
115
146
  };
116
147
  });
117
148
 
@@ -186,9 +217,24 @@ export const generateFilterOptions = (
186
217
  )
187
218
  };
188
219
 
220
+ // Filter out null filters and ensure items arrays don't contain undefined values
221
+ const cleanFilters = dynamicFilters
222
+ .filter(f => f != null && f.items != null)
223
+ .map(f => ({
224
+ ...f,
225
+ items: f.items.filter(item => item != null && item.name != null)
226
+ }));
227
+
228
+ const cleanLocations = locations
229
+ .filter(l => l != null && l.items != null)
230
+ .map(l => ({
231
+ ...l,
232
+ items: l.items.filter(item => item != null && item.name != null)
233
+ }));
234
+
189
235
  return {
190
- filters: dynamicFilters,
191
- locations: locations,
236
+ filters: cleanFilters,
237
+ locations: cleanLocations,
192
238
  pointsOfInterest: pointsOfInterest
193
239
  };
194
240
  }
@@ -235,7 +281,7 @@ export const applyFilters = async (
235
281
  });
236
282
  } else if (Object.keys(filterItems).length > 0) {
237
283
  results = results.filter(listing =>
238
- filterItems.hasOwnProperty(listing.fields[formattedField])
284
+ Object.prototype.hasOwnProperty.call(filterItems, listing.fields[formattedField])
239
285
  );
240
286
  }
241
287
  }
@@ -314,7 +360,7 @@ export const filterListingsByLocation = (
314
360
  let results = allListings;
315
361
  if (selectedLocation !== null) {
316
362
  results = results.filter(item =>
317
- selectedLocation.items.hasOwnProperty(item.id)
363
+ Object.prototype.hasOwnProperty.call(selectedLocation.items, item.id)
318
364
  );
319
365
  }
320
366
  const mapItems = getDistinctItemsByProximity(results, listingEntities);
@@ -0,0 +1,6 @@
1
+ import { extendTailwindMerge } from 'tailwind-merge';
2
+
3
+ // Create a custom tailwind-merge that understands the hc- prefix
4
+ export const twMerge = extendTailwindMerge({
5
+ prefix: 'hc-'
6
+ });