@geotab/zenith 3.17.0-beta.1 → 3.17.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.
Files changed (64) hide show
  1. package/README.md +26 -29
  2. package/dist/button/button.d.ts +1 -2
  3. package/dist/button/button.js +5 -22
  4. package/dist/button/buttonDisabledProps.d.ts +35 -0
  5. package/dist/button/buttonDisabledProps.js +33 -0
  6. package/dist/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +1 -1
  7. package/dist/dropdownRaw/dropdownHelper.d.ts +20 -3
  8. package/dist/dropdownRaw/dropdownHelper.js +29 -6
  9. package/dist/dropdownRaw/dropdownRaw.js +22 -6
  10. package/dist/header/components/collapsedItemsControl/collapsedItemsControl.js +1 -1
  11. package/dist/header/headerButton.d.ts +15 -2
  12. package/dist/header/headerButton.js +11 -6
  13. package/dist/index.css +4 -8
  14. package/dist/menu/components/menuButton.js +40 -58
  15. package/dist/pageHeader/pageHeaderButton.d.ts +15 -1
  16. package/dist/pageHeader/pageHeaderButton.js +8 -6
  17. package/dist/pillExpandable/pillExpandable.js +3 -1
  18. package/dist/pillExpandable/pillExpandableSimple.d.ts +2 -1
  19. package/dist/pillExpandable/pillExpandableSimple.js +2 -2
  20. package/dist/table/selectable/interfaces.d.ts +6 -0
  21. package/dist/table/selectable/useDragSelection.d.ts +1 -1
  22. package/dist/table/selectable/useDragSelection.js +4 -4
  23. package/dist/table/selectable/useSelectableRows.d.ts +2 -0
  24. package/dist/table/selectable/useSelectableRows.js +88 -41
  25. package/dist/table/selectable/utils/calculateSelectionState.js +3 -2
  26. package/dist/table/selectable/utils/getCurrentPageSelection.js +9 -4
  27. package/dist/table/selectable/utils/groupExclusions.d.ts +7 -0
  28. package/dist/table/selectable/utils/groupExclusions.js +61 -0
  29. package/dist/table/selectable/utils/isRowChecked.js +1 -1
  30. package/dist/table/table.js +6 -5
  31. package/dist/tooltip/tooltip.d.ts +5 -3
  32. package/dist/tooltip/tooltip.js +11 -9
  33. package/esm/button/button.d.ts +1 -2
  34. package/esm/button/button.js +5 -22
  35. package/esm/button/buttonDisabledProps.d.ts +35 -0
  36. package/esm/button/buttonDisabledProps.js +29 -0
  37. package/esm/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +1 -1
  38. package/esm/dropdownRaw/dropdownHelper.d.ts +20 -3
  39. package/esm/dropdownRaw/dropdownHelper.js +27 -5
  40. package/esm/dropdownRaw/dropdownRaw.js +23 -7
  41. package/esm/header/components/collapsedItemsControl/collapsedItemsControl.js +1 -1
  42. package/esm/header/headerButton.d.ts +15 -2
  43. package/esm/header/headerButton.js +11 -6
  44. package/esm/menu/components/menuButton.js +40 -58
  45. package/esm/pageHeader/pageHeaderButton.d.ts +15 -1
  46. package/esm/pageHeader/pageHeaderButton.js +8 -6
  47. package/esm/pillExpandable/pillExpandable.js +3 -1
  48. package/esm/pillExpandable/pillExpandableSimple.d.ts +2 -1
  49. package/esm/pillExpandable/pillExpandableSimple.js +2 -2
  50. package/esm/table/selectable/interfaces.d.ts +6 -0
  51. package/esm/table/selectable/useDragSelection.d.ts +1 -1
  52. package/esm/table/selectable/useDragSelection.js +4 -4
  53. package/esm/table/selectable/useSelectableRows.d.ts +2 -0
  54. package/esm/table/selectable/useSelectableRows.js +90 -43
  55. package/esm/table/selectable/utils/calculateSelectionState.js +3 -2
  56. package/esm/table/selectable/utils/getCurrentPageSelection.js +9 -4
  57. package/esm/table/selectable/utils/groupExclusions.d.ts +7 -0
  58. package/esm/table/selectable/utils/groupExclusions.js +55 -0
  59. package/esm/table/selectable/utils/isRowChecked.js +1 -1
  60. package/esm/table/table.js +6 -5
  61. package/esm/tooltip/tooltip.d.ts +5 -3
  62. package/esm/tooltip/tooltip.js +11 -9
  63. package/package.json +1 -1
  64. package/README.md.baseline +0 -1
@@ -17,6 +17,7 @@ import { useTableChildren } from "./children/useTableChildren";
17
17
  import { DeviceType } from "../commonHelpers/hooks/deviceType";
18
18
  import { useMobile } from "../commonHelpers/hooks/useMobile";
19
19
  import { getCurrentPageSelection } from "./selectable/utils/getCurrentPageSelection";
20
+ import { resolveGroupExclusions } from "./selectable/utils/groupExclusions";
20
21
  import { TableFullscreen } from "./children/tableFullscreen";
21
22
  import { TableBulkActions } from "./children/tableBulkActions";
22
23
  import { TablePagination } from "./children/tablePagination";
@@ -185,7 +186,7 @@ const TableInner = ({
185
186
  active,
186
187
  onClick
187
188
  }) => {
188
- var _a, _b, _c, _d, _e;
189
+ var _a, _b, _c, _d, _e, _f;
189
190
  const isMobile = useMobile();
190
191
  const {
191
192
  translate
@@ -279,15 +280,15 @@ const TableInner = ({
279
280
  var _a, _b;
280
281
  return isAllSelection((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all, (_b = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _b === void 0 ? void 0 : _b.selected.length, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions);
281
282
  }, [(_c = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _c === void 0 ? void 0 : _c.all, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, (_d = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _d === void 0 ? void 0 : _d.selected.length]);
283
+ const resolvedSelection = useMemo(() => resolveGroupExclusions(entities, selectable), [entities, selectable]);
282
284
  const selectionQty = useMemo(() => {
283
- var _a;
284
285
  if (!selectable) {
285
286
  return 0;
286
287
  }
287
- const ids = new Set((_a = selectable.selection) === null || _a === void 0 ? void 0 : _a.selected);
288
+ const ids = new Set(resolvedSelection === null || resolvedSelection === void 0 ? void 0 : resolvedSelection.selected);
288
289
  const base = entities.length > 0 ? entities : loadingEntities;
289
290
  return allSelected ? [...getCurrentPageSelection(base, selectable)].filter(id => !selectable.allowExclusions || !ids.has(id)).length : ids.size;
290
- }, [selectable, entities, loadingEntities, allSelected]);
291
+ }, [selectable, resolvedSelection, entities, loadingEntities, allSelected]);
291
292
  const clearSelection = useCallback(() => {
292
293
  setSelectMode(false);
293
294
  selectable === null || selectable === void 0 ? void 0 : selectable.onSelect({
@@ -313,7 +314,7 @@ const TableInner = ({
313
314
  detailPanel,
314
315
  footer,
315
316
  other
316
- } = useTableChildren(children, isMobile, selectionQty, allSelected, clearSelection, activeId, gridRef, onCloseDetailPanel, isInfinite, entities.length, (selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && ((_e = selectable.selection) === null || _e === void 0 ? void 0 : _e.all) ? new Set(selectable.selection.selected).size : 0, (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) !== "nested" && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible), !!feedEndCallback || !!isLoading);
317
+ } = useTableChildren(children, isMobile, selectionQty, allSelected, clearSelection, activeId, gridRef, onCloseDetailPanel, isInfinite, entities.length, (selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && (resolvedSelection === null || resolvedSelection === void 0 ? void 0 : resolvedSelection.all) ? new Set(resolvedSelection.selected).size + ((_f = (_e = resolvedSelection.excludedGroupIds) === null || _e === void 0 ? void 0 : _e.length) !== null && _f !== void 0 ? _f : 0) : 0, (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) !== "nested" && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible), !!feedEndCallback || !!isLoading);
317
318
  const hasDetailPanel = !!detailPanel;
318
319
  const shouldEnableRowClick = hasDetailPanel || !!onClick;
319
320
  const activeIdForRow = shouldEnableRowClick ? activeId : undefined;
@@ -5,11 +5,13 @@ import { TAlignment } from "../absolute/absolute";
5
5
  import { IInlineTrigger } from "./components/inlineTrigger";
6
6
  export type TooltipSize = "large" | "small" | "auto";
7
7
  export type TMobileView = "default" | "mobileSheet";
8
+ interface ITriggerDisabledProps {
9
+ disabled?: boolean;
10
+ "aria-disabled"?: boolean | "true" | "false";
11
+ }
8
12
  interface ITooltip extends IZenComponentProps {
9
- trigger?: ReactElement<PropsWithChildren & {
13
+ trigger?: ReactElement<PropsWithChildren & ITriggerDisabledProps & {
10
14
  onClick?: (e: React.MouseEvent) => void;
11
- disabled?: boolean;
12
- focusableWhenDisabled?: boolean;
13
15
  }>;
14
16
  alignment?: TAlignment;
15
17
  triggerClassName?: string;
@@ -110,12 +110,14 @@ const getInitialDeviceType = () => {
110
110
  }
111
111
  return DeviceType.Desktop;
112
112
  };
113
+ // A disabled trigger (native `disabled`, or `aria-disabled` when it must stay focusable) never runs its own
114
+ // `onClick`, so the tooltip has to react to the click capture phase instead.
115
+ const isTriggerDisabled = props => Boolean(props === null || props === void 0 ? void 0 : props.disabled) || (props === null || props === void 0 ? void 0 : props["aria-disabled"]) === true || (props === null || props === void 0 ? void 0 : props["aria-disabled"]) === "true";
113
116
  const EventWrapper = ({
114
117
  children,
115
118
  deviceType,
116
119
  onKeyDownHandler,
117
120
  handleUniversalClick,
118
- isTriggerDisabledFocusable,
119
121
  setTooltipVisible,
120
122
  timerRef,
121
123
  timerMouseLeaveRef,
@@ -124,8 +126,9 @@ const EventWrapper = ({
124
126
  const isCurrentDeviceDesktop = deviceType === DeviceType.Desktop;
125
127
  const triggerProps = children.props;
126
128
  const originalOnClick = triggerProps.onClick;
127
- // A disabled-focusable trigger's own `onClick` is a no-op guard, so `composedOnClick` never runs on
128
- // mobile — see the `onClickCapture` handling in `mobileEvents` below.
129
+ // A disabled trigger doesn't run its own `onClick`, so on mobile the tap is handled in the capture phase
130
+ // instead — see `mobileEvents` below.
131
+ const isDisabledTrigger = isTriggerDisabled(triggerProps);
129
132
  const composedOnClick = useCallback(e => {
130
133
  // Call original onClick first if it exists
131
134
  if (originalOnClick) {
@@ -164,7 +167,7 @@ const EventWrapper = ({
164
167
  }, [handleUniversalClick]);
165
168
  const mobileEvents = Object.assign({
166
169
  onKeyDown: mobileOnKeyDown
167
- }, isTriggerDisabledFocusable ? {
170
+ }, isDisabledTrigger ? {
168
171
  onClickCapture: handleUniversalClick
169
172
  } : {
170
173
  onClick: composedOnClick
@@ -199,7 +202,7 @@ export const Tooltip = ({
199
202
  const [deviceType, setDeviceType] = useState(getInitialDeviceType);
200
203
  const isMobile = deviceType === DeviceType.Mobile;
201
204
  const triggerProps = trigger === null || trigger === void 0 ? void 0 : trigger.props;
202
- const isTriggerDisabledFocusable = Boolean(triggerProps === null || triggerProps === void 0 ? void 0 : triggerProps.disabled) && (triggerProps === null || triggerProps === void 0 ? void 0 : triggerProps.focusableWhenDisabled) !== false;
205
+ const isDisabledTrigger = isTriggerDisabled(triggerProps);
203
206
  const tooltipId = useId();
204
207
  const {
205
208
  translate
@@ -230,7 +233,7 @@ export const Tooltip = ({
230
233
  }
231
234
  };
232
235
  const handleUniversalClick = useCallback(e => {
233
- const hasExternalClickHandler = !!(triggerProps === null || triggerProps === void 0 ? void 0 : triggerProps.onClick) && !isTriggerDisabledFocusable;
236
+ const hasExternalClickHandler = !!(triggerProps === null || triggerProps === void 0 ? void 0 : triggerProps.onClick) && !isDisabledTrigger;
234
237
  if (deviceType === DeviceType.Desktop) {
235
238
  setTooltipVisible(currentVisible => {
236
239
  if (currentVisible) {
@@ -239,14 +242,14 @@ export const Tooltip = ({
239
242
  return currentVisible;
240
243
  });
241
244
  } else {
242
- if (!isTriggerDisabledFocusable) {
245
+ if (!isDisabledTrigger) {
243
246
  e === null || e === void 0 ? void 0 : e.stopPropagation();
244
247
  }
245
248
  if (!hasExternalClickHandler) {
246
249
  setTooltipVisible(isVisible => !isVisible);
247
250
  }
248
251
  }
249
- }, [deviceType, isTriggerDisabledFocusable, triggerProps]);
252
+ }, [deviceType, isDisabledTrigger, triggerProps]);
250
253
  // Apply `triggerAriaLabel` to a `Tooltip.InlineTrigger` trigger (it has no `ariaLabel` prop
251
254
  // of its own); the default info-icon trigger below handles `triggerAriaLabel` separately.
252
255
  // An `aria-label` set directly on the `Tooltip.InlineTrigger` element takes priority over
@@ -273,7 +276,6 @@ export const Tooltip = ({
273
276
  isTooltipVisible: isTooltipVisible,
274
277
  onKeyDownHandler: onKeyDownHandler,
275
278
  handleUniversalClick: handleUniversalClick,
276
- isTriggerDisabledFocusable: isTriggerDisabledFocusable,
277
279
  setTooltipVisible: setTooltipVisible,
278
280
  timerRef: timerRef,
279
281
  timerMouseLeaveRef: timerMouseLeaveRef,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geotab/zenith",
3
- "version": "3.17.0-beta.1",
3
+ "version": "3.17.0",
4
4
  "description": "Zenith components library on React",
5
5
  "main": "dist/index.js",
6
6
  "types": "esm/index.d.ts",
@@ -1 +0,0 @@
1
- ac687d695edcc0c6ffdc6c27e69c5729e7b02d180623c4f81049d72111f97d0d