@foodpilot/foods 2.11.36 → 2.11.37

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.
@@ -19,6 +19,8 @@ const Legend = (props) => {
19
19
  valuesFormatterFn
20
20
  } = props;
21
21
  if (!labels || !labels.length) return null;
22
+ const total = (values == null ? void 0 : values.reduce((sum, value) => sum + (Number.isFinite(value) && value > 0 ? value : 0), 0)) ?? 0;
23
+ if ((legend == null ? void 0 : legend.mode) !== "raw" && values && values.length > 0 && total <= 0) return null;
22
24
  if ((legend == null ? void 0 : legend.position) === "bottom") {
23
25
  return /* @__PURE__ */ jsx(
24
26
  LegendBottom,
@@ -7,14 +7,32 @@ const createPalette = (colors, values) => {
7
7
  return chroma.scale(colors).colors(values.length);
8
8
  };
9
9
  const createDistribution = (values) => {
10
- const total = values.reduce((sum, value) => sum + value, 0);
11
- if (!total) {
10
+ const sanitized = values.map((value) => Number.isFinite(value) && value > 0 ? value : 0);
11
+ const total = sanitized.reduce((sum, value) => sum + value, 0);
12
+ if (total <= 0) {
12
13
  return [...new Array(values.length)].map(() => 0);
13
14
  }
14
- const proportions = values.map((value) => {
15
- return value / total * 100;
15
+ const exact = sanitized.map((value) => value / total * 100);
16
+ const floors = exact.map((value) => Math.floor(value));
17
+ const floorSum = floors.reduce((sum, value) => sum + value, 0);
18
+ const missing = Math.max(0, Math.min(values.length, 100 - floorSum));
19
+ const ranked = exact.map((value, index) => ({
20
+ index,
21
+ remainder: value - floors[index],
22
+ raw: sanitized[index]
23
+ })).sort((a, b) => {
24
+ const remainderDiff = b.remainder - a.remainder;
25
+ if (remainderDiff !== 0) return remainderDiff;
26
+ const rawDiff = b.raw - a.raw;
27
+ if (rawDiff !== 0) return rawDiff;
28
+ return a.index - b.index;
16
29
  });
17
- return proportions;
30
+ const result = [...floors];
31
+ for (let i = 0; i < missing; i += 1) {
32
+ const targetIndex = ranked[i].index;
33
+ result[targetIndex] = (result[targetIndex] ?? 0) + 1;
34
+ }
35
+ return result;
18
36
  };
19
37
  const dispatchMouseEventOnChart = (element, x, y) => {
20
38
  if (!element) return;
@@ -16,16 +16,18 @@ const UserButtons = (props) => {
16
16
  gap: "4px"
17
17
  },
18
18
  children: buttons.map((button, index) => {
19
+ const keyBase = button.type === "link" || button.type === "topLink" || button.type === "drawer" ? button.label : button.type;
20
+ const key = `${keyBase}-${index}`;
19
21
  if (button.type === "custom") {
20
22
  const component = button.render({
21
23
  isExpanded,
22
24
  extendSidebar,
23
25
  onMobileDrawerClose
24
26
  });
25
- return /* @__PURE__ */ jsx(CustomRender, { isExpanded, children: component });
27
+ return /* @__PURE__ */ jsx(CustomRender, { isExpanded, children: component }, key);
26
28
  }
27
29
  if (button.type === "separator") {
28
- return /* @__PURE__ */ jsx(Separator, { isExpanded });
30
+ return /* @__PURE__ */ jsx(Separator, { isExpanded }, key);
29
31
  }
30
32
  if (button.type === "drawer") {
31
33
  return /* @__PURE__ */ jsx(
@@ -36,7 +38,7 @@ const UserButtons = (props) => {
36
38
  extendSidebar,
37
39
  onMobileDrawerClose
38
40
  },
39
- index
41
+ key
40
42
  );
41
43
  }
42
44
  if (button.type === "topLink") {
@@ -47,7 +49,7 @@ const UserButtons = (props) => {
47
49
  isExpanded,
48
50
  onMobileDrawerClose
49
51
  },
50
- index
52
+ key
51
53
  );
52
54
  }
53
55
  return /* @__PURE__ */ jsx(
@@ -57,7 +59,7 @@ const UserButtons = (props) => {
57
59
  isExpanded,
58
60
  onMobileDrawerClose
59
61
  },
60
- index
62
+ key
61
63
  );
62
64
  })
63
65
  }
@@ -7,7 +7,8 @@ const a11yProps = (index) => {
7
7
  };
8
8
  };
9
9
  const SpecialTab = styled((props) => {
10
- return /* @__PURE__ */ jsx(Tab, { disableRipple: true, ...a11yProps(props.value), ...props });
10
+ const { variant: _variant, isSelected: _isSelected, textVariant: _textVariant, ...rest } = props;
11
+ return /* @__PURE__ */ jsx(Tab, { disableRipple: true, ...a11yProps(props.value), ...rest });
11
12
  })((props) => {
12
13
  const { theme, variant, textVariant = "body-bold" } = props;
13
14
  const typographyTheme = textVariant === "inherit" ? {} : theme.typography[textVariant];
@@ -63,20 +63,22 @@ const FoodsTabs = (props) => {
63
63
  icon: /* @__PURE__ */ jsx(Box, { display: "flex", alignItems: "center", children: /* @__PURE__ */ jsx(FoodsIcon, { icon: tab.icon, size: 2 }) }),
64
64
  iconPosition: "start",
65
65
  ...extraTabProps
66
- }
66
+ },
67
+ String(tab.id ?? tabIndex)
67
68
  );
68
69
  })
69
70
  }
70
71
  ) });
71
72
  };
72
73
  const SpecialTabs = styled((props) => {
73
- const { variant } = props;
74
+ const { tabVariant: _tabVariant, ...rest } = props;
75
+ const { variant } = rest;
74
76
  return /* @__PURE__ */ jsx(
75
77
  Tabs,
76
78
  {
77
79
  scrollButtons: variant === "scrollable" ? "auto" : false,
78
80
  allowScrollButtonsMobile: variant === "scrollable",
79
- ...props
81
+ ...rest
80
82
  }
81
83
  );
82
84
  })((props) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@foodpilot/foods",
3
3
  "private": false,
4
- "version": "2.11.36",
4
+ "version": "2.11.37",
5
5
  "type": "module",
6
6
  "main": "./dist/main.js",
7
7
  "module": "./dist/main.js",
@@ -305,7 +305,7 @@
305
305
  "@tiptap/pm": "^2.26.1",
306
306
  "@tiptap/react": "^2.26.1",
307
307
  "@tiptap/starter-kit": "^2.26.1",
308
- "ajv": "^8.17.1",
308
+ "ajv": "^8.18.0",
309
309
  "chroma-js": "^2.4.2",
310
310
  "i18next": "^23.0.0 || ^25.0.0",
311
311
  "i18next-browser-languagedetector": "^7.2.0",