@empoweredvote/ev-ui 0.9.0 → 0.9.2

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/dist/index.mjs CHANGED
@@ -43,7 +43,9 @@ function RadarChartCore({
43
43
  labelFontSize = 18,
44
44
  padding = 80,
45
45
  labelOffset = 20,
46
- tightFit = false
46
+ tightFit = false,
47
+ maxLabelLines = 2,
48
+ showLabels = true
47
49
  }) {
48
50
  const { isDark } = useTheme();
49
51
  const radius = size / 2 - 40;
@@ -109,21 +111,22 @@ function RadarChartCore({
109
111
  });
110
112
  const labelMeta = spokes.map(([shortTitle], i) => {
111
113
  const angle = 2 * Math.PI * i / numSpokes;
114
+ const sinA = Math.sin(angle);
115
+ const side = sinA < -0.1 ? "left" : sinA > 0.1 ? "right" : "center";
116
+ if (!showLabels) return { estimatedWidth: 0, side };
112
117
  const baseFSize = labelFontSize;
113
- const lines = wrapLabel(shortTitle, 12);
118
+ const lines = wrapLabel(shortTitle, 12, maxLabelLines);
114
119
  const longestLineLen = lines.reduce(
115
120
  (max, ln) => ln.length > max ? ln.length : max,
116
121
  0
117
122
  );
118
123
  const fSize = adaptiveFontSize(longestLineLen, baseFSize);
119
124
  const estimatedWidth = longestLineLen * fSize * 0.6;
120
- const sinA = Math.sin(angle);
121
- const side = sinA < -0.1 ? "left" : sinA > 0.1 ? "right" : "center";
122
125
  return { estimatedWidth, side };
123
126
  });
124
127
  const leftLabelWidths = labelMeta.filter((m) => m.side === "left").map((m) => m.estimatedWidth);
125
128
  const rightLabelWidths = labelMeta.filter((m) => m.side === "right").map((m) => m.estimatedWidth);
126
- const minPadding = 40;
129
+ const minPadding = showLabels ? 40 : 10;
127
130
  const maxPadding = padding * 2;
128
131
  const rawLeftPadding = Math.min(
129
132
  Math.max(
@@ -153,7 +156,8 @@ function RadarChartCore({
153
156
  if (y < yMin) yMin = y;
154
157
  if (y > yMax) yMax = y;
155
158
  }
156
- const labelMargin = labelOffset + labelFontSize * 1.4 + labelFontSize * 1.1;
159
+ const effLabelFSize = adaptiveFontSize(12, labelFontSize);
160
+ const labelMargin = showLabels ? labelOffset + effLabelFSize * 1.1 * maxLabelLines : 8;
157
161
  tightTop = yMin - labelMargin;
158
162
  tightHeight = yMax + labelMargin - tightTop;
159
163
  }
@@ -198,14 +202,14 @@ function RadarChartCore({
198
202
  }
199
203
  );
200
204
  }),
201
- spokes.map(([shortTitle], i) => {
205
+ showLabels && spokes.map(([shortTitle], i) => {
202
206
  const angle = 2 * Math.PI * i / numSpokes;
203
207
  const anchor = angle > Math.PI ? "end" : angle < Math.PI && angle > 0 ? "start" : "middle";
204
208
  const cosA = Math.cos(angle);
205
209
  const isTop = cosA > 0.5;
206
210
  const isBottom = cosA < -0.5;
207
211
  const baseFSize = labelFontSize;
208
- const lines = wrapLabel(shortTitle, 12);
212
+ const lines = wrapLabel(shortTitle, 12, maxLabelLines);
209
213
  const longestLine = lines.reduce(
210
214
  (max, ln) => ln.length > max ? ln.length : max,
211
215
  0
@@ -346,7 +350,7 @@ function RadarChartCore({
346
350
  function adaptiveFontSize(longestLineLen, baseFSize) {
347
351
  return Math.max(baseFSize, 10);
348
352
  }
349
- function wrapLabel(label, maxChars = 12) {
353
+ function wrapLabel(label, maxChars = 12, maxLines = 2) {
350
354
  const str = String(label);
351
355
  let rawWords;
352
356
  if (str.includes("/")) {
@@ -371,9 +375,9 @@ function wrapLabel(label, maxChars = 12) {
371
375
  }
372
376
  }
373
377
  if (line) lines.push(line);
374
- if (lines.length > 2) {
375
- const overflow = lines.splice(2).join(" ");
376
- lines[1] = lines[1] + " " + overflow;
378
+ if (lines.length > maxLines) {
379
+ const overflow = lines.splice(maxLines).join(" ");
380
+ lines[maxLines - 1] = lines[maxLines - 1] + " " + overflow;
377
381
  }
378
382
  return lines;
379
383
  }
@@ -1868,9 +1872,13 @@ function PoliticianCard({
1868
1872
  style = {},
1869
1873
  badge,
1870
1874
  imageFocalPoint,
1871
- footer
1875
+ footer,
1876
+ imageWidth = "90px",
1877
+ contentStyle = {}
1872
1878
  }) {
1873
1879
  const isHorizontal = variant === "horizontal";
1880
+ const imageWidthPx = parseInt(imageWidth, 10) || 90;
1881
+ const imageMinHeight = isHorizontal ? Math.ceil(imageWidthPx * 4 / 3) : void 0;
1874
1882
  const handleCardClick = (e) => {
1875
1883
  if (e.target.closest(".ev-compass-button")) return;
1876
1884
  onClick == null ? void 0 : onClick();
@@ -1891,25 +1899,29 @@ function PoliticianCard({
1891
1899
  cursor: onClick ? "pointer" : "default",
1892
1900
  transition: "box-shadow 0.2s ease, transform 0.2s ease",
1893
1901
  position: "relative",
1894
- minHeight: isHorizontal ? "130px" : void 0,
1902
+ minHeight: imageMinHeight,
1895
1903
  height: "100%",
1896
1904
  ...style
1897
1905
  },
1898
1906
  imageWrapper: {
1899
- width: isHorizontal ? "90px" : "100%",
1907
+ // Horizontal: fixed width with 3:4 aspect ratio so portrait photos look
1908
+ // consistent regardless of card content height.
1909
+ position: "relative",
1910
+ width: isHorizontal ? imageWidth : "100%",
1900
1911
  height: isHorizontal ? "100%" : "auto",
1901
- maxHeight: isHorizontal ? "200px" : void 0,
1902
1912
  aspectRatio: isHorizontal ? void 0 : "4/5",
1903
1913
  flexShrink: 0,
1904
1914
  overflow: "hidden"
1905
1915
  },
1906
1916
  image: {
1917
+ ...isHorizontal ? { position: "absolute", top: 0, left: 0 } : {},
1907
1918
  width: "100%",
1908
1919
  height: "100%",
1909
1920
  objectFit: "cover",
1910
1921
  objectPosition: imageFocalPoint != null ? imageFocalPoint : "center 20%"
1911
1922
  },
1912
1923
  imagePlaceholder: {
1924
+ ...isHorizontal ? { position: "absolute", top: 0, left: 0 } : {},
1913
1925
  width: "100%",
1914
1926
  height: "100%",
1915
1927
  backgroundColor: colors.evTeal,
@@ -1927,7 +1939,8 @@ function PoliticianCard({
1927
1939
  padding: isHorizontal ? `${spacing[2]} ${spacing[3]}` : spacing[3],
1928
1940
  minWidth: 0,
1929
1941
  display: "flex",
1930
- flexDirection: "column"
1942
+ flexDirection: "column",
1943
+ ...contentStyle
1931
1944
  },
1932
1945
  name: {
1933
1946
  fontFamily: fonts.primary,