@geotab/zenith 3.8.0-beta.1 → 3.8.1-beta.0

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/README.md CHANGED
@@ -54,22 +54,26 @@ Zenith library provides components defined in Zenith Design System. It includes
54
54
 
55
55
  ## Change log
56
56
 
57
+ ### 3.8.1
58
+
59
+ - Fix horizontal pie chart center text scaling and legend toggle
60
+
57
61
  ### 3.8.0
58
62
 
59
- - Create reusable File upload component
60
- - Improve Accordion component Storybook documentation
61
- - Improve Divider component Storybook documentation
62
- - Improve accessibility for DataGrid sorting
63
- - Create Chip component documentation
64
- - Update sort controls in mobile Table
65
- - Improve accessibility for Radio button
66
- - Improve accessibility for SummaryTiles
67
- - Accessibility updates for Dropdown, MobileSheet, ControlledPopup
63
+ - Create `FileUpload` component
64
+ - Improve `Accordion` component Storybook documentation
65
+ - Improve `Divider` component Storybook documentation
66
+ - Improve accessibility for `DataGrid` sorting
67
+ - Create `Chip` component documentation
68
+ - Update sort controls in mobile `Table`
69
+ - Improve accessibility for `Radio` button
70
+ - Improve accessibility for `SummaryTile`
71
+ - Accessibility updates for `Dropdown`, `MobileSheet`, `ControlledPopup`
68
72
  - Add Prettier CI job to Zenith pipeline
69
- - SummaryTile refactor, documentation updates
73
+ - `SummaryTile` refactor, documentation updates
70
74
  - Updated translations
71
75
  - Add multiline table header support (word wrap for long strings)
72
- - SidePanel outside click improvements
76
+ - `SidePanel` outside click improvements
73
77
 
74
78
  ### 3.7.0
75
79
 
@@ -645,7 +645,7 @@ const buttonType_1 = require("../button/buttonType");
645
645
  const zen_1 = require("../utils/zen");
646
646
  const DEFAULT_START_DAY_OF_WEEK = 0;
647
647
  const DEFAULT_YEAR_RANGE = 20;
648
- exports.monthLabelsArray = ["Jan", "Feb", "Mar", "Apr", "Ma", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
648
+ exports.monthLabelsArray = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
649
649
  const Calendar = ({
650
650
  id,
651
651
  value,
@@ -16,16 +16,23 @@ const centerTextPlugin = (centerText) => ({
16
16
  const css = (name) => getCssVar(chart.canvas, name);
17
17
  const fontFamily = css("--main-font");
18
18
  const hasLabel = !!centerText.label;
19
- const valueY = hasLabel ? centerY - 14 : centerY;
19
+ const meta = chart.getDatasetMeta(0);
20
+ const controllerRadius = meta.controller.innerRadius;
21
+ const innerRadius = typeof controllerRadius === "number" && controllerRadius > 0 ? controllerRadius : Math.min(width, height) * 0.325;
22
+ const maxValueFont = parseFloat(css("--pie-center-value-font-size")) || 28;
23
+ const maxLabelFont = parseFloat(css("--pie-center-label-font-size")) || 14;
24
+ const valueFontSize = Math.max(10, Math.min(maxValueFont, innerRadius * 0.45));
25
+ const labelFontSize = Math.max(8, Math.min(maxLabelFont, innerRadius * 0.22));
26
+ const valueY = hasLabel ? centerY - valueFontSize * 0.5 : centerY;
20
27
  ctx.textAlign = "center";
21
28
  ctx.textBaseline = "middle";
22
- ctx.font = `${css("--pie-center-value-font-weight")} ${css("--pie-center-value-font-size")} ${fontFamily}`;
29
+ ctx.font = `${css("--pie-center-value-font-weight")} ${valueFontSize}px ${fontFamily}`;
23
30
  ctx.fillStyle = css("--text-primary");
24
31
  ctx.fillText(String(centerText.value), centerX, valueY);
25
32
  if (hasLabel) {
26
- ctx.font = `${css("--pie-center-label-font-weight")} ${css("--pie-center-label-font-size")} ${fontFamily}`;
33
+ ctx.font = `${css("--pie-center-label-font-weight")} ${labelFontSize}px ${fontFamily}`;
27
34
  ctx.fillStyle = css("--text-secondary");
28
- ctx.fillText(String(centerText.label), centerX, centerY + 16);
35
+ ctx.fillText(String(centerText.label), centerX, centerY + labelFontSize * 1.1);
29
36
  }
30
37
  ctx.restore();
31
38
  }
@@ -59,7 +59,16 @@ const PieChart = (_a) => {
59
59
  }, [fontSize, dark]);
60
60
  const defOptions = (0, react_1.useMemo)(() => (0, getDefaultOptions_1.getDefaultOptions)(), []);
61
61
  const chartOptions = (0, utils_1.deepMerge)(defOptions, options);
62
- const { isHidden, toggleHidden } = (0, useHidden_1.useHidden)();
62
+ const { isHidden, toggleHidden: rawToggle } = (0, useHidden_1.useHidden)();
63
+ const pieData = data.datasets[0].data;
64
+ const toggleHidden = (0, react_1.useCallback)((index) => {
65
+ if (!isHidden(index)) {
66
+ const visibleCount = pieData.filter((_, i) => !isHidden(i)).length;
67
+ if (visibleCount <= 1)
68
+ return;
69
+ }
70
+ rawToggle(index);
71
+ }, [isHidden, rawToggle, pieData]);
63
72
  const chartData = (0, react_1.useMemo)(() => {
64
73
  const chData = Object.assign({}, data);
65
74
  chData.datasets = chData.datasets.map(ds => (0, getDefaultDatasetStyle_1.getDefaultDatasetStyle)(ds));
package/dist/index.js CHANGED
@@ -18,7 +18,6 @@ exports.IconVolumeHalf = exports.IconVolumeFull = exports.IconVolumeDown = expor
18
18
  exports.isButton = exports.findPrevFocusable = exports.findNextFocusable = exports.findLastFocusable = exports.findFirstFocusable = exports.Menu = exports.ControlledMenu = exports.isDragNotClick = exports.changeOrder = exports.ListItem = exports.List = exports.ItemData = exports.ItemCompact = exports.LineChartMini = exports.getDefaultDatasetStyle = exports.htmlLegendPlugin = exports.LEGEND_PLUGIN_ID = exports.LineChart = exports.useLayoutSize = exports.LayoutFullScreenProvider = exports.useLayoutFullScreen = exports.LayoutFullScreenElementProvider = exports.useLayoutFullScreenElement = exports.Layout = exports.ImageTapToUpload = exports.ImageNothingFound = exports.ImageNoMatchingAssets = exports.ImageLooking = exports.ImageCloudUpload = exports.ImageAdjustFilter = exports.IconZoom2 = exports.IconZoom = exports.IconZone = exports.IconYen = exports.IconWrite = exports.IconWrench = exports.IconWorld = exports.IconWorkday = exports.IconWifi2 = exports.IconWifi = exports.IconWhisper = exports.IconWebcam = exports.IconWatch2 = exports.IconWatch = exports.IconWarning = exports.IconWallet1 = exports.IconWallet = exports.IconVolumeOn = exports.IconVolumeOff = exports.IconVolumeMinimum = void 0;
19
19
  exports.SummaryTileBarDisplayName = exports.SummaryTileBar = exports.getTypeClassName = exports.SummaryTileTrigger = exports.SummaryTile = exports.SummaryTileDisplayName = exports.SummaryTileSize = exports.SummaryTileType = exports.Summary = exports.Summaries = exports.Stepper = exports.SortControl = exports.SortDirections = exports.Skeleton = exports.LazyContent = exports.SidePanel = exports.CUSTOM_POPUP_COMPONENT_CLASSNAME = exports.SidePanelCloseReason = exports.isChildPopup = exports.SelectField = exports.Select = exports.SearchInput = exports.Range = exports.RadioGroup = exports.Radio = exports.ProgressBar = exports.ProgreesBarSize = exports.ProgressBarType = exports.PrimaryIcon = exports.Popup = exports.PillExpandable = exports.Pill = exports.PaginationType = exports.Pagination = exports.PageLayout = exports.PageContentLayout = exports.PageHeaderMenu = exports.PageHeaderMenuDisplayName = exports.PageHeaderButton = exports.PageHeaderButtonDisplayName = exports.PageHeader = exports.PageHeaderDisplayName = exports.Notification = exports.getPredefinedFocusableItem = exports.DialogContentNew = exports.Modal = exports.MobileSheet = exports.MiniTabs = exports.MiniTabsSize = exports.isLink = void 0;
20
20
  exports.Waiting = exports.UserFormatProvider = exports.useDrive = exports.ThemeProvider = exports.ThemeDrive = exports.ThemeDark = exports.useLanguage = exports.injectString = exports.dictionaries = exports.LanguageProvider = exports.getFirstFocusableItem = exports.getNewFocusableItem = exports.HeaderButtonsProvider = exports.AbortablePromise = exports.Tooltip = exports.removeArrowClasses = exports.calculateArrowPosition = exports.ToggleButtonRaw = exports.ToggleButton = exports.Toast = exports.useToast = exports.TimePicker = exports.TextareaRaw = exports.Textarea = exports.TextInputRaw = exports.TextInput = exports.TextIconButton = exports.ButtonIconPosition = exports.Tabs = exports.TabsDisplayName = exports.ActionLinkColumn = exports.CheckboxColumn = exports.MainColumn = exports.ActionsColumn = exports.getSortableValue = exports.ColumnSortDirection = exports.getEmptySelection = exports.Table = exports.useNestedRows = exports.NestedData = exports.TabBarContent = exports.TabBar = void 0;
21
- /* eslint-disable max-len */
22
21
  var absolute_1 = require("./absolute/absolute");
23
22
  Object.defineProperty(exports, "Absolute", { enumerable: true, get: function () { return absolute_1.Absolute; } });
24
23
  var accordion_1 = require("./accordion/accordion");
@@ -54,8 +54,6 @@ export interface ISummaryTile extends IZenComponentProps, IZenGridItem {
54
54
  tooltipSize?: TooltipSize;
55
55
  /** When `true`, shows a skeleton placeholder while data is being fetched — two skeleton elements replace the title and content areas. */
56
56
  isLoading?: boolean;
57
- /** When `true` and the tile is interactive, sets `aria-current="page"` on the tile. */
58
- isSelected?: boolean;
59
57
  /** Analytics identifier applied as `data-analytics-id`. Defaults to a kebab-cased version of `title`. */
60
58
  dataAnalyticsId?: string;
61
59
  }
@@ -75,6 +73,6 @@ export declare const SummaryTileDisplayName = "SummaryTile";
75
73
  * Use inside `SummaryTileBar` to group multiple tiles in a scrollable row.
76
74
  */
77
75
  export declare const SummaryTile: {
78
- ({ className, children, size, title, tileType, id, onClick, tooltipText, tooltipAlignment, isLoading, isSelected, dataAnalyticsId }: ISummaryTile): import("react/jsx-runtime").JSX.Element;
76
+ ({ className, children, size, title, tileType, id, onClick, tooltipText, tooltipAlignment, isLoading, dataAnalyticsId }: ISummaryTile): import("react/jsx-runtime").JSX.Element;
79
77
  displayName: string;
80
78
  };
@@ -122,7 +122,6 @@ const SummaryTile = ({
122
122
  tooltipText,
123
123
  tooltipAlignment = "top",
124
124
  isLoading = false,
125
- isSelected = false,
126
125
  dataAnalyticsId
127
126
  }) => {
128
127
  const {
@@ -178,7 +177,7 @@ const SummaryTile = ({
178
177
  }),
179
178
  children: tooltipText
180
179
  }) : null;
181
- const ariaCurrentProps = isSelected && isInteractive ? {
180
+ const ariaCurrentProps = tileType === SummaryTileType.Active && isInteractive ? {
182
181
  "aria-current": "page"
183
182
  } : {};
184
183
  // When both onClick and tooltipText are present, the tooltip trigger
@@ -637,7 +637,7 @@ injectString("ro-RO", "Next month", "Luna urm\u0103toare");
637
637
  injectString("ar-SA", "Next month", "\u0627\u0644\u0634\u0647\u0631 \u0627\u0644\u062A\u0627\u0644\u064A");
638
638
  const DEFAULT_START_DAY_OF_WEEK = 0;
639
639
  const DEFAULT_YEAR_RANGE = 20;
640
- export const monthLabelsArray = ["Jan", "Feb", "Mar", "Apr", "Ma", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
640
+ export const monthLabelsArray = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
641
641
  export const Calendar = ({
642
642
  id,
643
643
  value,
@@ -13,16 +13,23 @@ export const centerTextPlugin = (centerText) => ({
13
13
  const css = (name) => getCssVar(chart.canvas, name);
14
14
  const fontFamily = css("--main-font");
15
15
  const hasLabel = !!centerText.label;
16
- const valueY = hasLabel ? centerY - 14 : centerY;
16
+ const meta = chart.getDatasetMeta(0);
17
+ const controllerRadius = meta.controller.innerRadius;
18
+ const innerRadius = typeof controllerRadius === "number" && controllerRadius > 0 ? controllerRadius : Math.min(width, height) * 0.325;
19
+ const maxValueFont = parseFloat(css("--pie-center-value-font-size")) || 28;
20
+ const maxLabelFont = parseFloat(css("--pie-center-label-font-size")) || 14;
21
+ const valueFontSize = Math.max(10, Math.min(maxValueFont, innerRadius * 0.45));
22
+ const labelFontSize = Math.max(8, Math.min(maxLabelFont, innerRadius * 0.22));
23
+ const valueY = hasLabel ? centerY - valueFontSize * 0.5 : centerY;
17
24
  ctx.textAlign = "center";
18
25
  ctx.textBaseline = "middle";
19
- ctx.font = `${css("--pie-center-value-font-weight")} ${css("--pie-center-value-font-size")} ${fontFamily}`;
26
+ ctx.font = `${css("--pie-center-value-font-weight")} ${valueFontSize}px ${fontFamily}`;
20
27
  ctx.fillStyle = css("--text-primary");
21
28
  ctx.fillText(String(centerText.value), centerX, valueY);
22
29
  if (hasLabel) {
23
- ctx.font = `${css("--pie-center-label-font-weight")} ${css("--pie-center-label-font-size")} ${fontFamily}`;
30
+ ctx.font = `${css("--pie-center-label-font-weight")} ${labelFontSize}px ${fontFamily}`;
24
31
  ctx.fillStyle = css("--text-secondary");
25
- ctx.fillText(String(centerText.label), centerX, centerY + 16);
32
+ ctx.fillText(String(centerText.label), centerX, centerY + labelFontSize * 1.1);
26
33
  }
27
34
  ctx.restore();
28
35
  }
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { useContext, useEffect, useId, useMemo, useRef } from "react";
13
+ import { useCallback, useContext, useEffect, useId, useMemo, useRef } from "react";
14
14
  import { Pie } from "../react-chartjs/typedCharts";
15
15
  import { Chart as ChartJS, PieController, ArcElement } from "chart.js/auto";
16
16
  import "../react-chartjs/dateAdapter";
@@ -56,7 +56,16 @@ export const PieChart = (_a) => {
56
56
  }, [fontSize, dark]);
57
57
  const defOptions = useMemo(() => getDefaultOptions(), []);
58
58
  const chartOptions = deepMerge(defOptions, options);
59
- const { isHidden, toggleHidden } = useHidden();
59
+ const { isHidden, toggleHidden: rawToggle } = useHidden();
60
+ const pieData = data.datasets[0].data;
61
+ const toggleHidden = useCallback((index) => {
62
+ if (!isHidden(index)) {
63
+ const visibleCount = pieData.filter((_, i) => !isHidden(i)).length;
64
+ if (visibleCount <= 1)
65
+ return;
66
+ }
67
+ rawToggle(index);
68
+ }, [isHidden, rawToggle, pieData]);
60
69
  const chartData = useMemo(() => {
61
70
  const chData = Object.assign({}, data);
62
71
  chData.datasets = chData.datasets.map(ds => getDefaultDatasetStyle(ds));
@@ -54,8 +54,6 @@ export interface ISummaryTile extends IZenComponentProps, IZenGridItem {
54
54
  tooltipSize?: TooltipSize;
55
55
  /** When `true`, shows a skeleton placeholder while data is being fetched — two skeleton elements replace the title and content areas. */
56
56
  isLoading?: boolean;
57
- /** When `true` and the tile is interactive, sets `aria-current="page"` on the tile. */
58
- isSelected?: boolean;
59
57
  /** Analytics identifier applied as `data-analytics-id`. Defaults to a kebab-cased version of `title`. */
60
58
  dataAnalyticsId?: string;
61
59
  }
@@ -75,6 +73,6 @@ export declare const SummaryTileDisplayName = "SummaryTile";
75
73
  * Use inside `SummaryTileBar` to group multiple tiles in a scrollable row.
76
74
  */
77
75
  export declare const SummaryTile: {
78
- ({ className, children, size, title, tileType, id, onClick, tooltipText, tooltipAlignment, isLoading, isSelected, dataAnalyticsId }: ISummaryTile): import("react/jsx-runtime").JSX.Element;
76
+ ({ className, children, size, title, tileType, id, onClick, tooltipText, tooltipAlignment, isLoading, dataAnalyticsId }: ISummaryTile): import("react/jsx-runtime").JSX.Element;
79
77
  displayName: string;
80
78
  };
@@ -83,7 +83,6 @@ export const SummaryTile = ({
83
83
  tooltipText,
84
84
  tooltipAlignment = "top",
85
85
  isLoading = false,
86
- isSelected = false,
87
86
  dataAnalyticsId
88
87
  }) => {
89
88
  const {
@@ -139,7 +138,7 @@ export const SummaryTile = ({
139
138
  }),
140
139
  children: tooltipText
141
140
  }) : null;
142
- const ariaCurrentProps = isSelected && isInteractive ? {
141
+ const ariaCurrentProps = tileType === SummaryTileType.Active && isInteractive ? {
143
142
  "aria-current": "page"
144
143
  } : {};
145
144
  // When both onClick and tooltipText are present, the tooltip trigger
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geotab/zenith",
3
- "version": "3.8.0-beta.1",
3
+ "version": "3.8.1-beta.0",
4
4
  "description": "Zenith components library on React",
5
5
  "main": "dist/index.js",
6
6
  "types": "esm/index.d.ts",