@abcagency/hc-ui-components 1.8.7 → 1.8.9

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.
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import useListLogic from '../../../hooks/useList.js';
3
3
  import { useMap } from '../../../contexts/mapContext.js';
4
4
  import { useMapList } from '../../../contexts/mapListContext.js';
@@ -15,22 +15,33 @@ const ItemsListContainer = ({ fieldNames, showMap, fieldsShown, specialFeatures
15
15
  const { selectedListItem } = useMap();
16
16
  const { trackEvent, eventTypes } = useTrackEvent();
17
17
  const itemExpandedContent = (item, recruiter) => item ? (ExpandListComponent ? React.createElement(ExpandListComponent, { listing: item }) : React.createElement(ListingDetailsContainer, { item: item, recruiter: recruiter })) : null;
18
- if (!fieldsShown.includes('travelTime') && commuteLocation != null && Object.entries(commuteLocation).length > 0 && !noEntities) {
19
- fieldsShown.push('travelTime');
20
- fieldNames['travelTime'] = 'Commute';
21
- }
22
- else if (fieldsShown.includes('travelTime') && (!commuteLocation || noEntities)) {
23
- fieldsShown = fieldsShown.filter(x => x !== 'travelTime');
24
- }
18
+ // Track if component has mounted to avoid hydration mismatch with localStorage
19
+ const [hasMounted, setHasMounted] = React.useState(false);
20
+ React.useEffect(() => {
21
+ setHasMounted(true);
22
+ }, []);
23
+ // Use useMemo to avoid hydration mismatch - create new array instead of mutating prop
24
+ // Don't add travelTime until after mount to avoid SSR/client mismatch from localStorage
25
+ const effectiveFieldsShown = useMemo(() => {
26
+ const fields = [...fieldsShown];
27
+ if (hasMounted && !fields.includes('travelTime') && commuteLocation != null && Object.entries(commuteLocation).length > 0 && !noEntities) {
28
+ fields.push('travelTime');
29
+ fieldNames['travelTime'] = 'Commute';
30
+ }
31
+ else if (fields.includes('travelTime') && (!commuteLocation || noEntities)) {
32
+ return fields.filter(x => x !== 'travelTime');
33
+ }
34
+ return fields;
35
+ }, [fieldsShown, commuteLocation, noEntities, fieldNames, hasMounted]);
25
36
  const setTrackedSortSetting = (sortSetting) => {
26
37
  trackEvent(eventTypes.LIST_SORTED, sortSetting);
27
38
  setSortSetting(sortSetting);
28
39
  };
29
40
  //fieldsShown.push('favorite');
30
- return (React.createElement(ItemsList, { fieldNames: fieldNames, showMap: showMap, fieldsShown: fieldsShown, filteredListings: filteredListings, loading: loading, sortSetting: sortSetting, setSortSetting: setTrackedSortSetting, itemLimit: itemLimit, loader: loader, scrollContainerRef: scrollContainerRef, itemRefs: itemRefs, selectedListItem: selectedListItem, includeFavorite: true },
41
+ return (React.createElement(ItemsList, { fieldNames: fieldNames, showMap: showMap, fieldsShown: effectiveFieldsShown, filteredListings: filteredListings, loading: loading, sortSetting: sortSetting, setSortSetting: setTrackedSortSetting, itemLimit: itemLimit, loader: loader, scrollContainerRef: scrollContainerRef, itemRefs: itemRefs, selectedListItem: selectedListItem, includeFavorite: true },
31
42
  React.createElement(Accordion, { className: "hc-divide-y hc-divide-uiAccent/10", defaultValue: selectedListItem?.id }, (sortSetting ? dynamicSort(filteredListings, sortSetting.field, sortSetting.type, favorites) : filteredListings)
32
43
  .slice(0, itemLimit)
33
- .map((item) => (React.createElement(MapAccordionItemContainer, { key: item.id, showMap: showMap, item: item, itemRefs: itemRefs, fieldsShown: fieldsShown, itemExpandedContent: itemExpandedContent, specialFeatures: specialFeatures, isActive: selectedListItem?.id === item.id }))))));
44
+ .map((item, index) => (React.createElement(MapAccordionItemContainer, { key: item.id, showMap: showMap, item: item, itemRefs: itemRefs, fieldsShown: effectiveFieldsShown, itemExpandedContent: itemExpandedContent, specialFeatures: specialFeatures, isActive: selectedListItem?.id === item.id, index: index }))))));
34
45
  };
35
46
 
36
47
  export { ItemsListContainer as default };
@@ -1 +1 @@
1
- {"version":3,"file":"item-list-container.js","sources":["../../../../src/components/containers/list/item-list-container.tsx"],"sourcesContent":["import React from 'react';\nimport useListLogic from '~/hooks/useList';\nimport { useMap } from '~/contexts/mapContext';\nimport { useMapList } from '~/contexts/mapListContext';\nimport { useTrackEvent } from '~/contexts/trackEventContext';\nimport ItemsList from '~/components/modules/list/item-list';\nimport Accordion from '~/components/modules/accordions/default';\nimport MapAccordionItemContainer from '~/components/containers/accordions/map-accordion-item-container';\nimport { dynamicSort } from '~/util/sortUtil';\nimport { Listing } from '~/types/Listings';\nimport ListingDetailsContainer from '../jobListing/listing-details-container';\n\ninterface ItemsListContainerProps {\n fieldNames: Record<string, string>;\n showMap: boolean;\n fieldsShown: string[];\n specialFeatures: any;\n}\n\nconst ItemsListContainer: React.FC<ItemsListContainerProps> = ({\n\tfieldNames,\n\tshowMap,\n\tfieldsShown,\n\tspecialFeatures\n}) => {\n\tconst { filteredListings, loading, commuteLocation, sortSetting, setSortSetting, ExpandListComponent, favorites, noEntities } = useMapList();\n\tconst { itemLimit, loader, scrollContainerRef, itemRefs } = useListLogic(filteredListings as any);\n\tconst { selectedListItem } = useMap();\n\tconst { trackEvent, eventTypes } = useTrackEvent() as any;\n\tconst itemExpandedContent = (item: any, recruiter: any) =>\n\t\titem ? (ExpandListComponent ? <ExpandListComponent listing={item} /> : <ListingDetailsContainer item={item} recruiter={recruiter} />) : null;\n\n\tif (!fieldsShown.includes('travelTime') && commuteLocation != null && Object.entries(commuteLocation).length > 0 && !noEntities) {\n\t\tfieldsShown.push('travelTime');\n\t\tfieldNames['travelTime'] = 'Commute';\n\t} else if (fieldsShown.includes('travelTime') && (!commuteLocation || noEntities)) {\n\t\tfieldsShown = fieldsShown.filter(x => x !== 'travelTime');\n\t}\n\n\tconst setTrackedSortSetting = (sortSetting: { field: string; type: string }) => {\n\t\ttrackEvent(eventTypes.LIST_SORTED, sortSetting);\n\t\tsetSortSetting(sortSetting);\n\t};\n\t\t//fieldsShown.push('favorite');\n\n\treturn (\n\t\t<ItemsList\n\t\t\tfieldNames={fieldNames}\n\t\t\tshowMap={showMap}\n\t\t\tfieldsShown={fieldsShown}\n\t\t\tfilteredListings={filteredListings}\n\t\t\tloading={loading}\n\t\t\tsortSetting={sortSetting}\n\t\t\tsetSortSetting={setTrackedSortSetting}\n\t\t\titemLimit={itemLimit}\n\t\t\tloader={loader}\n\t\t\tscrollContainerRef={scrollContainerRef}\n\t\t\titemRefs={itemRefs}\n\t\t\tselectedListItem={selectedListItem}\n\t\t\tincludeFavorite={true}\n\t\t>\n\t\t\t<Accordion className=\"hc-divide-y hc-divide-uiAccent/10\" defaultValue={selectedListItem?.id}>\n\t\t\t\t{(sortSetting ? dynamicSort(filteredListings, sortSetting.field, sortSetting.type, favorites as any) : filteredListings)\n\t\t\t\t\t.slice(0, itemLimit)\n\t\t\t\t\t.map((item: Listing) => (\n\t\t\t\t\t\t<MapAccordionItemContainer\n\t\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t\tshowMap={showMap}\n\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\titemRefs={itemRefs}\n\t\t\t\t\t\t\tfieldsShown={fieldsShown}\n\t\t\t\t\t\t\titemExpandedContent={itemExpandedContent}\n\t\t\t\t\t\t\tspecialFeatures={specialFeatures}\n\t\t\t\t\t\t\tisActive={selectedListItem?.id === item.id}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t</Accordion>\n\t\t</ItemsList>\n\t);\n};\n\nexport default ItemsListContainer;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"item-list-container.js","sources":["../../../../src/components/containers/list/item-list-container.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport useListLogic from '~/hooks/useList';\nimport { useMap } from '~/contexts/mapContext';\nimport { useMapList } from '~/contexts/mapListContext';\nimport { useTrackEvent } from '~/contexts/trackEventContext';\nimport ItemsList from '~/components/modules/list/item-list';\nimport Accordion from '~/components/modules/accordions/default';\nimport MapAccordionItemContainer from '~/components/containers/accordions/map-accordion-item-container';\nimport { dynamicSort } from '~/util/sortUtil';\nimport { Listing } from '~/types/Listings';\nimport ListingDetailsContainer from '../jobListing/listing-details-container';\n\ninterface ItemsListContainerProps {\n fieldNames: Record<string, string>;\n showMap: boolean;\n fieldsShown: string[];\n specialFeatures: any;\n}\n\nconst ItemsListContainer: React.FC<ItemsListContainerProps> = ({\n\tfieldNames,\n\tshowMap,\n\tfieldsShown,\n\tspecialFeatures\n}) => {\n\tconst { filteredListings, loading, commuteLocation, sortSetting, setSortSetting, ExpandListComponent, favorites, noEntities } = useMapList();\n\tconst { itemLimit, loader, scrollContainerRef, itemRefs } = useListLogic(filteredListings as any);\n\tconst { selectedListItem } = useMap();\n\tconst { trackEvent, eventTypes } = useTrackEvent() as any;\n\tconst itemExpandedContent = (item: any, recruiter: any) =>\n\t\titem ? (ExpandListComponent ? <ExpandListComponent listing={item} /> : <ListingDetailsContainer item={item} recruiter={recruiter} />) : null;\n\n\t// Track if component has mounted to avoid hydration mismatch with localStorage\n\tconst [hasMounted, setHasMounted] = React.useState(false);\n\tReact.useEffect(() => {\n\t\tsetHasMounted(true);\n\t}, []);\n\n\t// Use useMemo to avoid hydration mismatch - create new array instead of mutating prop\n\t// Don't add travelTime until after mount to avoid SSR/client mismatch from localStorage\n\tconst effectiveFieldsShown = useMemo(() => {\n\t\tconst fields = [...fieldsShown];\n\t\tif (hasMounted && !fields.includes('travelTime') && commuteLocation != null && Object.entries(commuteLocation).length > 0 && !noEntities) {\n\t\t\tfields.push('travelTime');\n\t\t\tfieldNames['travelTime'] = 'Commute';\n\t\t} else if (fields.includes('travelTime') && (!commuteLocation || noEntities)) {\n\t\t\treturn fields.filter(x => x !== 'travelTime');\n\t\t}\n\t\treturn fields;\n\t}, [fieldsShown, commuteLocation, noEntities, fieldNames, hasMounted]);\n\n\tconst setTrackedSortSetting = (sortSetting: { field: string; type: string }) => {\n\t\ttrackEvent(eventTypes.LIST_SORTED, sortSetting);\n\t\tsetSortSetting(sortSetting);\n\t};\n\t\t//fieldsShown.push('favorite');\n\n\treturn (\n\t\t<ItemsList\n\t\t\tfieldNames={fieldNames}\n\t\t\tshowMap={showMap}\n\t\t\tfieldsShown={effectiveFieldsShown}\n\t\t\tfilteredListings={filteredListings}\n\t\t\tloading={loading}\n\t\t\tsortSetting={sortSetting}\n\t\t\tsetSortSetting={setTrackedSortSetting}\n\t\t\titemLimit={itemLimit}\n\t\t\tloader={loader}\n\t\t\tscrollContainerRef={scrollContainerRef}\n\t\t\titemRefs={itemRefs}\n\t\t\tselectedListItem={selectedListItem}\n\t\t\tincludeFavorite={true}\n\t\t>\n\t\t\t<Accordion className=\"hc-divide-y hc-divide-uiAccent/10\" defaultValue={selectedListItem?.id}>\n\t\t\t\t{(sortSetting ? dynamicSort(filteredListings, sortSetting.field, sortSetting.type, favorites as any) : filteredListings)\n\t\t\t\t\t.slice(0, itemLimit)\n\t\t\t\t\t.map((item: Listing, index: number) => (\n\t\t\t\t\t\t<MapAccordionItemContainer\n\t\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t\tshowMap={showMap}\n\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\titemRefs={itemRefs}\n\t\t\t\t\t\t\tfieldsShown={effectiveFieldsShown}\n\t\t\t\t\t\t\titemExpandedContent={itemExpandedContent}\n\t\t\t\t\t\t\tspecialFeatures={specialFeatures}\n\t\t\t\t\t\t\tisActive={selectedListItem?.id === item.id}\n\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t</Accordion>\n\t\t</ItemsList>\n\t);\n};\n\nexport default ItemsListContainer;\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abcagency/hc-ui-components",
3
- "version": "1.8.7",
3
+ "version": "1.8.9",
4
4
  "description": "UI Components for HireControl",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import useListLogic from '~/hooks/useList';
3
3
  import { useMap } from '~/contexts/mapContext';
4
4
  import { useMapList } from '~/contexts/mapListContext';
@@ -30,12 +30,24 @@ const ItemsListContainer: React.FC<ItemsListContainerProps> = ({
30
30
  const itemExpandedContent = (item: any, recruiter: any) =>
31
31
  item ? (ExpandListComponent ? <ExpandListComponent listing={item} /> : <ListingDetailsContainer item={item} recruiter={recruiter} />) : null;
32
32
 
33
- if (!fieldsShown.includes('travelTime') && commuteLocation != null && Object.entries(commuteLocation).length > 0 && !noEntities) {
34
- fieldsShown.push('travelTime');
35
- fieldNames['travelTime'] = 'Commute';
36
- } else if (fieldsShown.includes('travelTime') && (!commuteLocation || noEntities)) {
37
- fieldsShown = fieldsShown.filter(x => x !== 'travelTime');
38
- }
33
+ // Track if component has mounted to avoid hydration mismatch with localStorage
34
+ const [hasMounted, setHasMounted] = React.useState(false);
35
+ React.useEffect(() => {
36
+ setHasMounted(true);
37
+ }, []);
38
+
39
+ // Use useMemo to avoid hydration mismatch - create new array instead of mutating prop
40
+ // Don't add travelTime until after mount to avoid SSR/client mismatch from localStorage
41
+ const effectiveFieldsShown = useMemo(() => {
42
+ const fields = [...fieldsShown];
43
+ if (hasMounted && !fields.includes('travelTime') && commuteLocation != null && Object.entries(commuteLocation).length > 0 && !noEntities) {
44
+ fields.push('travelTime');
45
+ fieldNames['travelTime'] = 'Commute';
46
+ } else if (fields.includes('travelTime') && (!commuteLocation || noEntities)) {
47
+ return fields.filter(x => x !== 'travelTime');
48
+ }
49
+ return fields;
50
+ }, [fieldsShown, commuteLocation, noEntities, fieldNames, hasMounted]);
39
51
 
40
52
  const setTrackedSortSetting = (sortSetting: { field: string; type: string }) => {
41
53
  trackEvent(eventTypes.LIST_SORTED, sortSetting);
@@ -47,7 +59,7 @@ const ItemsListContainer: React.FC<ItemsListContainerProps> = ({
47
59
  <ItemsList
48
60
  fieldNames={fieldNames}
49
61
  showMap={showMap}
50
- fieldsShown={fieldsShown}
62
+ fieldsShown={effectiveFieldsShown}
51
63
  filteredListings={filteredListings}
52
64
  loading={loading}
53
65
  sortSetting={sortSetting}
@@ -62,16 +74,17 @@ const ItemsListContainer: React.FC<ItemsListContainerProps> = ({
62
74
  <Accordion className="hc-divide-y hc-divide-uiAccent/10" defaultValue={selectedListItem?.id}>
63
75
  {(sortSetting ? dynamicSort(filteredListings, sortSetting.field, sortSetting.type, favorites as any) : filteredListings)
64
76
  .slice(0, itemLimit)
65
- .map((item: Listing) => (
77
+ .map((item: Listing, index: number) => (
66
78
  <MapAccordionItemContainer
67
79
  key={item.id}
68
80
  showMap={showMap}
69
81
  item={item}
70
82
  itemRefs={itemRefs}
71
- fieldsShown={fieldsShown}
83
+ fieldsShown={effectiveFieldsShown}
72
84
  itemExpandedContent={itemExpandedContent}
73
85
  specialFeatures={specialFeatures}
74
86
  isActive={selectedListItem?.id === item.id}
87
+ index={index}
75
88
  />
76
89
  ))}
77
90
  </Accordion>