@performant-software/semantic-components 0.5.20-beta.0 → 0.5.20-beta.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@performant-software/semantic-components",
3
- "version": "0.5.20-beta.0",
3
+ "version": "0.5.20-beta.3",
4
4
  "description": "A package of shared components based on the Semantic UI Framework.",
5
5
  "license": "MIT",
6
6
  "main": "./build/index.js",
@@ -12,7 +12,7 @@
12
12
  "build": "webpack --mode production && flow-copy-source -v src types"
13
13
  },
14
14
  "dependencies": {
15
- "@performant-software/shared-components": "^0.5.20-beta.0",
15
+ "@performant-software/shared-components": "^0.5.20-beta.3",
16
16
  "@react-google-maps/api": "^2.8.1",
17
17
  "axios": "^0.26.1",
18
18
  "i18next": "^19.4.4",
@@ -5,7 +5,12 @@ import {
5
5
  GoogleMap as MapComponent,
6
6
  Marker
7
7
  } from '@react-google-maps/api';
8
- import React, { useCallback, useEffect, useState } from 'react';
8
+ import React, {
9
+ useCallback,
10
+ useEffect,
11
+ useMemo,
12
+ useState
13
+ } from 'react';
9
14
 
10
15
  type LatLng = {
11
16
  lat: () => number,
@@ -37,28 +42,44 @@ const GoogleMap = (props: Props) => {
37
42
  const [center, setCenter] = useState(position || props.defaultCenter);
38
43
  const [map, setMap] = useState();
39
44
 
40
- // If no default zoom is provided and a position is provided, set the default zoom to 12.
41
- let { defaultZoom } = props;
45
+ /**
46
+ * Set the zoom value based on the position and defaultZoom prop.
47
+ *
48
+ * @type {*}
49
+ */
50
+ const zoom = useMemo(() => {
51
+ let value;
42
52
 
43
- if (!defaultZoom) {
44
53
  if (position) {
45
- defaultZoom = DEFAULT_ZOOM_MARKER;
54
+ value = DEFAULT_ZOOM_MARKER;
55
+ } else if (props.defaultZoom) {
56
+ value = props.defaultZoom;
46
57
  } else {
47
- defaultZoom = DEFAULT_ZOOM;
58
+ value = DEFAULT_ZOOM;
48
59
  }
49
- }
50
60
 
51
- // Call the onDragEnd prop, passing the new location.
52
- const onDragEnd = ({ latLng }) => {
61
+ return value;
62
+ }, [position, props.defaultZoom]);
63
+
64
+ /**
65
+ * Call the onDragEnd prop, passing the new location.
66
+ *
67
+ * @type {(function({latLng: *}): void)|*}
68
+ */
69
+ const onDragEnd = useCallback(({ latLng }) => {
53
70
  if (props.onDragEnd) {
54
- // $FlowFixMe - Not actually fixing, we're checking for presence here.
55
71
  props.onDragEnd({
56
72
  lat: latLng.lat(),
57
73
  lng: latLng.lng()
58
74
  });
59
75
  }
60
- };
76
+ }, [props.onDragEnd]);
61
77
 
78
+ /**
79
+ * Sets the map object when the component mounts.
80
+ *
81
+ * @type {function(*): void}
82
+ */
62
83
  const onLoad = useCallback((m) => setMap(m), []);
63
84
 
64
85
  // If the position is changed manually and the new location is outside of the current bounds, re-center the map.
@@ -78,7 +99,7 @@ const GoogleMap = (props: Props) => {
78
99
  mapContainerStyle={props.containerStyle}
79
100
  onClick={onDragEnd}
80
101
  onLoad={onLoad}
81
- zoom={defaultZoom}
102
+ zoom={zoom}
82
103
  >
83
104
  { position && (
84
105
  <Marker
@@ -3,6 +3,7 @@
3
3
  import React, {
4
4
  useCallback,
5
5
  useEffect,
6
+ useMemo,
6
7
  useRef,
7
8
  useState
8
9
  } from 'react';
@@ -37,9 +38,20 @@ const HorizontalCards = (props: Props) => {
37
38
  const ref = useRef();
38
39
 
39
40
  /**
40
- * Sets the number of pages and total page width on the state.
41
+ * Sets the flex-box style based on the page width.
42
+ *
43
+ * @type {function(): {flex: string}}
41
44
  */
42
- useEffect(() => {
45
+ const cardStyle = useMemo(() => ({
46
+ flex: `0 0 ${(pageWidth / props.perPage) - marginWidth}px`
47
+ }), [pageWidth, marginWidth, props.perPage]);
48
+
49
+ /**
50
+ * Initializes the page width and scroll pages on the sate.
51
+ *
52
+ * @type {(function(*=): void)|*}
53
+ */
54
+ const initialize = useCallback((event) => {
43
55
  const instance = ref.current;
44
56
 
45
57
  if (instance) {
@@ -48,6 +60,10 @@ const HorizontalCards = (props: Props) => {
48
60
  setPageWidth(clientWidth);
49
61
  setScrollPages(Math.ceil(scrollWidth / clientWidth));
50
62
 
63
+ if (!event) {
64
+ setScrollPage(0);
65
+ }
66
+
51
67
  const child = instance.firstChild;
52
68
  if (child) {
53
69
  const style = window.getComputedStyle(child);
@@ -57,6 +73,34 @@ const HorizontalCards = (props: Props) => {
57
73
  setMarginWidth(leftMargin + rightMargin);
58
74
  }
59
75
  }
76
+ }, [ref, props.items]);
77
+
78
+ /**
79
+ * Sets the current page number on the state.
80
+ *
81
+ * @type {function(*): void}
82
+ */
83
+ const onPageChange = useCallback((increment) => {
84
+ let nextPage = scrollPage + increment;
85
+
86
+ if (nextPage < 0) {
87
+ nextPage = scrollPages;
88
+ } else if (nextPage >= scrollPages) {
89
+ nextPage = 0;
90
+ }
91
+
92
+ setScrollPage(nextPage);
93
+ }, [scrollPage, scrollPages]);
94
+
95
+ /**
96
+ * Sets the window resize event listener.
97
+ */
98
+ useEffect(() => {
99
+ window.addEventListener('resize', initialize);
100
+
101
+ initialize();
102
+
103
+ return () => window.removeEventListener('resize', initialize);
60
104
  }, []);
61
105
 
62
106
  /**
@@ -82,32 +126,6 @@ const HorizontalCards = (props: Props) => {
82
126
  }
83
127
  }, [scrollPage, pageWidth]);
84
128
 
85
- /**
86
- * Sets the current page number on the state.
87
- *
88
- * @type {function(*): void}
89
- */
90
- const onPageChange = useCallback((increment) => {
91
- let nextPage = scrollPage + increment;
92
-
93
- if (nextPage < 0) {
94
- nextPage = scrollPages;
95
- } else if (nextPage >= scrollPages) {
96
- nextPage = 0;
97
- }
98
-
99
- setScrollPage(nextPage);
100
- }, [scrollPage, scrollPages]);
101
-
102
- /**
103
- * Returns the flex-box style based on the page width.
104
- *
105
- * @type {function(): {flex: string}}
106
- */
107
- const getCardStyle = useCallback(() => ({
108
- flex: `0 0 ${(pageWidth / props.perPage) - marginWidth}px`
109
- }), [pageWidth, marginWidth, props.perPage]);
110
-
111
129
  /**
112
130
  * Renders the card component. If a "route" prop is passed, the component is wrapped in a Link.
113
131
  *
@@ -119,35 +137,33 @@ const HorizontalCards = (props: Props) => {
119
137
  const renderCard = (item, index) => (
120
138
  <Card
121
139
  link
122
- onClick={() => {
123
- if (props.onClick) {
124
- props.onClick(item, index);
125
- }
126
- }}
127
- style={getCardStyle()}
140
+ onClick={props.onClick && props.onClick.bind(this, item, index)}
141
+ style={cardStyle}
128
142
  >
129
143
  { !props.inlineImage && renderImage(item) }
130
- <Card.Content>
131
- { props.inlineImage && renderImage(item) }
132
- { props.renderHeader && (
133
- <Card.Header
134
- as={Header}
135
- size='small'
136
- >
137
- { props.renderHeader(item) }
138
- </Card.Header>
139
- )}
140
- { props.renderMeta && (
141
- <Card.Meta>
142
- { props.renderMeta(item) }
143
- </Card.Meta>
144
- )}
145
- { props.renderDescription && (
146
- <Card.Description>
147
- { props.renderDescription(item) }
148
- </Card.Description>
149
- )}
150
- </Card.Content>
144
+ { (props.renderHeader || props.renderMeta || props.renderDescription) && (
145
+ <Card.Content>
146
+ { props.inlineImage && renderImage(item) }
147
+ { props.renderHeader && (
148
+ <Card.Header
149
+ as={Header}
150
+ size='small'
151
+ >
152
+ { props.renderHeader(item) }
153
+ </Card.Header>
154
+ )}
155
+ { props.renderMeta && (
156
+ <Card.Meta>
157
+ { props.renderMeta(item) }
158
+ </Card.Meta>
159
+ )}
160
+ { props.renderDescription && (
161
+ <Card.Description>
162
+ { props.renderDescription(item) }
163
+ </Card.Description>
164
+ )}
165
+ </Card.Content>
166
+ )}
151
167
  { props.renderExtra && (
152
168
  <Card.Content
153
169
  extra
@@ -5,7 +5,12 @@ import {
5
5
  GoogleMap as MapComponent,
6
6
  Marker
7
7
  } from '@react-google-maps/api';
8
- import React, { useCallback, useEffect, useState } from 'react';
8
+ import React, {
9
+ useCallback,
10
+ useEffect,
11
+ useMemo,
12
+ useState
13
+ } from 'react';
9
14
 
10
15
  type LatLng = {
11
16
  lat: () => number,
@@ -37,28 +42,44 @@ const GoogleMap = (props: Props) => {
37
42
  const [center, setCenter] = useState(position || props.defaultCenter);
38
43
  const [map, setMap] = useState();
39
44
 
40
- // If no default zoom is provided and a position is provided, set the default zoom to 12.
41
- let { defaultZoom } = props;
45
+ /**
46
+ * Set the zoom value based on the position and defaultZoom prop.
47
+ *
48
+ * @type {*}
49
+ */
50
+ const zoom = useMemo(() => {
51
+ let value;
42
52
 
43
- if (!defaultZoom) {
44
53
  if (position) {
45
- defaultZoom = DEFAULT_ZOOM_MARKER;
54
+ value = DEFAULT_ZOOM_MARKER;
55
+ } else if (props.defaultZoom) {
56
+ value = props.defaultZoom;
46
57
  } else {
47
- defaultZoom = DEFAULT_ZOOM;
58
+ value = DEFAULT_ZOOM;
48
59
  }
49
- }
50
60
 
51
- // Call the onDragEnd prop, passing the new location.
52
- const onDragEnd = ({ latLng }) => {
61
+ return value;
62
+ }, [position, props.defaultZoom]);
63
+
64
+ /**
65
+ * Call the onDragEnd prop, passing the new location.
66
+ *
67
+ * @type {(function({latLng: *}): void)|*}
68
+ */
69
+ const onDragEnd = useCallback(({ latLng }) => {
53
70
  if (props.onDragEnd) {
54
- // $FlowFixMe - Not actually fixing, we're checking for presence here.
55
71
  props.onDragEnd({
56
72
  lat: latLng.lat(),
57
73
  lng: latLng.lng()
58
74
  });
59
75
  }
60
- };
76
+ }, [props.onDragEnd]);
61
77
 
78
+ /**
79
+ * Sets the map object when the component mounts.
80
+ *
81
+ * @type {function(*): void}
82
+ */
62
83
  const onLoad = useCallback((m) => setMap(m), []);
63
84
 
64
85
  // If the position is changed manually and the new location is outside of the current bounds, re-center the map.
@@ -78,7 +99,7 @@ const GoogleMap = (props: Props) => {
78
99
  mapContainerStyle={props.containerStyle}
79
100
  onClick={onDragEnd}
80
101
  onLoad={onLoad}
81
- zoom={defaultZoom}
102
+ zoom={zoom}
82
103
  >
83
104
  { position && (
84
105
  <Marker
@@ -3,6 +3,7 @@
3
3
  import React, {
4
4
  useCallback,
5
5
  useEffect,
6
+ useMemo,
6
7
  useRef,
7
8
  useState
8
9
  } from 'react';
@@ -37,9 +38,20 @@ const HorizontalCards = (props: Props) => {
37
38
  const ref = useRef();
38
39
 
39
40
  /**
40
- * Sets the number of pages and total page width on the state.
41
+ * Sets the flex-box style based on the page width.
42
+ *
43
+ * @type {function(): {flex: string}}
41
44
  */
42
- useEffect(() => {
45
+ const cardStyle = useMemo(() => ({
46
+ flex: `0 0 ${(pageWidth / props.perPage) - marginWidth}px`
47
+ }), [pageWidth, marginWidth, props.perPage]);
48
+
49
+ /**
50
+ * Initializes the page width and scroll pages on the sate.
51
+ *
52
+ * @type {(function(*=): void)|*}
53
+ */
54
+ const initialize = useCallback((event) => {
43
55
  const instance = ref.current;
44
56
 
45
57
  if (instance) {
@@ -48,6 +60,10 @@ const HorizontalCards = (props: Props) => {
48
60
  setPageWidth(clientWidth);
49
61
  setScrollPages(Math.ceil(scrollWidth / clientWidth));
50
62
 
63
+ if (!event) {
64
+ setScrollPage(0);
65
+ }
66
+
51
67
  const child = instance.firstChild;
52
68
  if (child) {
53
69
  const style = window.getComputedStyle(child);
@@ -57,6 +73,34 @@ const HorizontalCards = (props: Props) => {
57
73
  setMarginWidth(leftMargin + rightMargin);
58
74
  }
59
75
  }
76
+ }, [ref, props.items]);
77
+
78
+ /**
79
+ * Sets the current page number on the state.
80
+ *
81
+ * @type {function(*): void}
82
+ */
83
+ const onPageChange = useCallback((increment) => {
84
+ let nextPage = scrollPage + increment;
85
+
86
+ if (nextPage < 0) {
87
+ nextPage = scrollPages;
88
+ } else if (nextPage >= scrollPages) {
89
+ nextPage = 0;
90
+ }
91
+
92
+ setScrollPage(nextPage);
93
+ }, [scrollPage, scrollPages]);
94
+
95
+ /**
96
+ * Sets the window resize event listener.
97
+ */
98
+ useEffect(() => {
99
+ window.addEventListener('resize', initialize);
100
+
101
+ initialize();
102
+
103
+ return () => window.removeEventListener('resize', initialize);
60
104
  }, []);
61
105
 
62
106
  /**
@@ -82,32 +126,6 @@ const HorizontalCards = (props: Props) => {
82
126
  }
83
127
  }, [scrollPage, pageWidth]);
84
128
 
85
- /**
86
- * Sets the current page number on the state.
87
- *
88
- * @type {function(*): void}
89
- */
90
- const onPageChange = useCallback((increment) => {
91
- let nextPage = scrollPage + increment;
92
-
93
- if (nextPage < 0) {
94
- nextPage = scrollPages;
95
- } else if (nextPage >= scrollPages) {
96
- nextPage = 0;
97
- }
98
-
99
- setScrollPage(nextPage);
100
- }, [scrollPage, scrollPages]);
101
-
102
- /**
103
- * Returns the flex-box style based on the page width.
104
- *
105
- * @type {function(): {flex: string}}
106
- */
107
- const getCardStyle = useCallback(() => ({
108
- flex: `0 0 ${(pageWidth / props.perPage) - marginWidth}px`
109
- }), [pageWidth, marginWidth, props.perPage]);
110
-
111
129
  /**
112
130
  * Renders the card component. If a "route" prop is passed, the component is wrapped in a Link.
113
131
  *
@@ -119,35 +137,33 @@ const HorizontalCards = (props: Props) => {
119
137
  const renderCard = (item, index) => (
120
138
  <Card
121
139
  link
122
- onClick={() => {
123
- if (props.onClick) {
124
- props.onClick(item, index);
125
- }
126
- }}
127
- style={getCardStyle()}
140
+ onClick={props.onClick && props.onClick.bind(this, item, index)}
141
+ style={cardStyle}
128
142
  >
129
143
  { !props.inlineImage && renderImage(item) }
130
- <Card.Content>
131
- { props.inlineImage && renderImage(item) }
132
- { props.renderHeader && (
133
- <Card.Header
134
- as={Header}
135
- size='small'
136
- >
137
- { props.renderHeader(item) }
138
- </Card.Header>
139
- )}
140
- { props.renderMeta && (
141
- <Card.Meta>
142
- { props.renderMeta(item) }
143
- </Card.Meta>
144
- )}
145
- { props.renderDescription && (
146
- <Card.Description>
147
- { props.renderDescription(item) }
148
- </Card.Description>
149
- )}
150
- </Card.Content>
144
+ { (props.renderHeader || props.renderMeta || props.renderDescription) && (
145
+ <Card.Content>
146
+ { props.inlineImage && renderImage(item) }
147
+ { props.renderHeader && (
148
+ <Card.Header
149
+ as={Header}
150
+ size='small'
151
+ >
152
+ { props.renderHeader(item) }
153
+ </Card.Header>
154
+ )}
155
+ { props.renderMeta && (
156
+ <Card.Meta>
157
+ { props.renderMeta(item) }
158
+ </Card.Meta>
159
+ )}
160
+ { props.renderDescription && (
161
+ <Card.Description>
162
+ { props.renderDescription(item) }
163
+ </Card.Description>
164
+ )}
165
+ </Card.Content>
166
+ )}
151
167
  { props.renderExtra && (
152
168
  <Card.Content
153
169
  extra