@geotab/zenith 3.6.0-beta.4 → 3.6.0-beta.6

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
@@ -49,11 +49,10 @@ Zenith library provides components defined in Zenith Design System. It includes
49
49
 
50
50
  ### 3.6.0
51
51
 
52
- Enhanced accessibility, improved component documentation, and new mobile features. Plus several component fixes and server-side rendering support exploration.
52
+ Enhanced accessibility, improved component documentation, several component fixes and new mobile features.
53
53
 
54
54
  Change log:
55
55
 
56
- - Add server-side rendering support exploration for Zenith
57
56
  - Create mobile version of new `Filters` component
58
57
  - Add defensive checks for Invalid Date objects in `DateRange` component
59
58
  - Integrate `Banner` into `Layout`
@@ -4,7 +4,7 @@ exports.useClientReady = void 0;
4
4
  const react_1 = require("react");
5
5
  const isDomEnv_1 = require("../isDomEnv");
6
6
  const useClientReady = () => {
7
- const [isClientReady, setIsClientReady] = (0, react_1.useState)(false);
7
+ const [isClientReady, setIsClientReady] = (0, react_1.useState)(true);
8
8
  (0, react_1.useEffect)(() => {
9
9
  if ((0, isDomEnv_1.isDomEnv)()) {
10
10
  setIsClientReady(true);
@@ -284,7 +284,7 @@ const DateRangeRaw = props => {
284
284
  const isCustomDateOption = (selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.label) === dateRangeInner_1.CUSTOM_CALENDAR_ID;
285
285
  const [isOpen, setIsOpen] = (0, react_1.useState)(false);
286
286
  const prevIsOpenRef = (0, react_1.useRef)(false);
287
- const datesValidation = (0, react_1.useCallback)(val => (0, getRangeOption_1.isValidDateFn)(allowUnsetValue)(val), [allowUnsetValue]);
287
+ const datesValidation = (0, react_1.useMemo)(() => (0, getRangeOption_1.isValidDateFn)(allowUnsetValue), [allowUnsetValue]);
288
288
  const isDatesValid = (0, react_1.useRef)(datesValidation(value));
289
289
  const [customDate, setCustomDate] = (0, react_1.useState)((0, normalizeDates_1.normalizeDates)((0, getRangeOption_1.isDateValid)(value === null || value === void 0 ? void 0 : value.from) ? value.from.toISOString() : undefined, (0, getRangeOption_1.isDateValid)(value === null || value === void 0 ? void 0 : value.to) ? value.to.toISOString() : undefined, disableFutureDates, disablePastDates, disableDatesBefore, disableDatesAfter));
290
290
  const isDefaultState = !defaultValue && !selectedRange || defaultValue && selectedRange && defaultValue.label === selectedRange.label && defaultValue.label !== dateRangeInner_1.CUSTOM_CALENDAR_ID || defaultValue && selectedRange && defaultValue.label === selectedRange.label && defaultValue.label === dateRangeInner_1.CUSTOM_CALENDAR_ID && customDate.from && customDate.to && new Date(customDate.from).toISOString() === defaultValue.from.toISOString() && new Date(customDate.to).toISOString() === defaultValue.to.toISOString();
@@ -21,7 +21,7 @@ const FiltersBarPeriodPicker = ({ props, hasApplyButton, className, useSidePanel
21
21
  const [selectedRange, setSelectedRange] = (0, react_1.useState)((0, getRangeOption_1.getSelectedRangeFromValue)(optionsMap, state));
22
22
  const filterBarLabelledId = (0, react_1.useId)();
23
23
  const [prevSelection, setPrevSelection] = (0, react_1.useState)((0, getRangeOption_1.getSelectedRangeFromValue)(optionsMap, state));
24
- const datesValidation = (0, react_1.useCallback)(val => (0, getRangeOption_1.isValidDateFn)(props.allowUnsetValue || false)(val), [props.allowUnsetValue]);
24
+ const datesValidation = (0, react_1.useMemo)(() => (0, getRangeOption_1.isValidDateFn)(props.allowUnsetValue || false), [props.allowUnsetValue]);
25
25
  const isDatesValid = (0, react_1.useRef)(datesValidation(state));
26
26
  const getCustomRange = (0, react_1.useCallback)(() => ({ from: (prevSelection === null || prevSelection === void 0 ? void 0 : prevSelection.from) || new Date(), to: (prevSelection === null || prevSelection === void 0 ? void 0 : prevSelection.to) || new Date() }), [prevSelection]);
27
27
  const options = (0, react_1.useMemo)(() => (0, getRangeOption_1.getRangeOptionsArray)(optionsArg, translate, toLocalDateTime, weekStartsOnSunday ? "Sunday" : "Monday", toReverseOffsetDateTime, withCalendar || false, prevSelection && prevSelection.label === dateRangeInner_1.CUSTOM_CALENDAR_ID, prevSelection ? getCustomRange : undefined), [optionsArg, translate, toLocalDateTime, weekStartsOnSunday, toReverseOffsetDateTime, withCalendar, prevSelection, getCustomRange]);
@@ -303,13 +303,8 @@ const GroupsFilterRaw = props => {
303
303
  const prevSearchField = (0, react_1.useRef)("");
304
304
  const groupsFilterId = (0, react_1.useId)();
305
305
  const popupId = (0, react_1.useId)();
306
+ const isDataLoadedRef = (0, react_1.useRef)(false);
306
307
  const blocksMap = (0, react_1.useMemo)(() => [["builtInGroups", "userGroups"], ["advancedGroups", "builtInGroups", "userGroups"], ["builtInGroups", "userGroups"]], []);
307
- const onOptionsToggle = (0, react_1.useCallback)(() => {
308
- dispatchUiState({
309
- type: uiStateActionType_1.UiStateActionType.ToggleOpen,
310
- payload: undefined
311
- });
312
- }, []);
313
308
  const handleSetStep = (0, react_1.useCallback)(newStep => {
314
309
  var _a;
315
310
  uiState.step !== groupsFilterInterfaces_1.FilterMenuStep.CurrentlySelected && dispatchUiState({
@@ -559,6 +554,7 @@ const GroupsFilterRaw = props => {
559
554
  return [];
560
555
  }), [dataLoader, errorHandler]);
561
556
  const loadData = (0, react_1.useCallback)(() => {
557
+ isDataLoadedRef.current = true;
562
558
  dispatchUiState({
563
559
  type: uiStateActionType_1.UiStateActionType.SetLoadWithError,
564
560
  payload: {
@@ -587,12 +583,32 @@ const GroupsFilterRaw = props => {
587
583
  isLoading: false
588
584
  }
589
585
  });
586
+ isDataLoadedRef.current = false;
590
587
  errorHandler(e);
591
588
  });
592
589
  }, [dataLoader, errorHandler]);
593
590
  (0, react_1.useEffect)(() => {
591
+ if (isDataLoadedRef.current) {
592
+ return;
593
+ }
594
594
  loadData();
595
595
  }, [loadData]);
596
+ const onOptionsToggle = (0, react_1.useCallback)(() => {
597
+ const willBeOpen = !uiState.isOpen;
598
+ dispatchUiState({
599
+ type: uiStateActionType_1.UiStateActionType.ToggleOpen,
600
+ payload: undefined
601
+ });
602
+ if (willBeOpen && !isDataLoadedRef.current && !uiState.isLoading) {
603
+ loadData();
604
+ }
605
+ }, [uiState.isOpen, uiState.isLoading, loadData]);
606
+ const isEmptyMap = dataItems.length === 0;
607
+ (0, react_1.useEffect)(() => {
608
+ if (isEmptyMap && uiState.isOpen && !uiState.isLoading && !uiState.hasError) {
609
+ loadData();
610
+ }
611
+ }, [uiState.isOpen, isEmptyMap, uiState.isLoading, uiState.hasError, loadData]);
596
612
  (0, react_1.useEffect)(() => {
597
613
  const step = uiState.step;
598
614
  if (step !== groupsFilterInterfaces_1.FilterMenuStep.CurrentlySelected) {
@@ -833,12 +849,6 @@ const GroupsFilterRaw = props => {
833
849
  children: translate("Clear")
834
850
  })]
835
851
  }), [handleApply, handleCancel, handleReset, isApplyDisabled, translate]);
836
- const isEmptyMap = dataItems.length === 0;
837
- (0, react_1.useEffect)(() => {
838
- if (isEmptyMap && uiState.isOpen && !uiState.isLoading && !uiState.hasError) {
839
- loadData();
840
- }
841
- }, [uiState.isOpen, isEmptyMap, uiState.isLoading, uiState.hasError, loadData]);
842
852
  const memoizedMobileView = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)(mobileSheet_1.MobileSheet, {
843
853
  label: translate("Organization groups filter"),
844
854
  triggerRef: triggerRef,
package/dist/index.css CHANGED
@@ -7758,7 +7758,7 @@
7758
7758
  text-transform: none;
7759
7759
  }
7760
7760
  .zen-text-input.zen-text-input--mobile {
7761
- padding: 13px 12px;
7761
+ padding: 11px 12px 12px;
7762
7762
  font-family: var(--main-font);
7763
7763
  font-size: 14px;
7764
7764
  font-style: normal;
@@ -1,7 +1,7 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import { isDomEnv } from "../isDomEnv";
3
3
  export const useClientReady = () => {
4
- const [isClientReady, setIsClientReady] = useState(false);
4
+ const [isClientReady, setIsClientReady] = useState(true);
5
5
  useEffect(() => {
6
6
  if (isDomEnv()) {
7
7
  setIsClientReady(true);
@@ -276,7 +276,7 @@ export const DateRangeRaw = props => {
276
276
  const isCustomDateOption = (selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.label) === CUSTOM_CALENDAR_ID;
277
277
  const [isOpen, setIsOpen] = useState(false);
278
278
  const prevIsOpenRef = useRef(false);
279
- const datesValidation = useCallback(val => isValidDateFn(allowUnsetValue)(val), [allowUnsetValue]);
279
+ const datesValidation = useMemo(() => isValidDateFn(allowUnsetValue), [allowUnsetValue]);
280
280
  const isDatesValid = useRef(datesValidation(value));
281
281
  const [customDate, setCustomDate] = useState(normalizeDates(isDateValid(value === null || value === void 0 ? void 0 : value.from) ? value.from.toISOString() : undefined, isDateValid(value === null || value === void 0 ? void 0 : value.to) ? value.to.toISOString() : undefined, disableFutureDates, disablePastDates, disableDatesBefore, disableDatesAfter));
282
282
  const isDefaultState = !defaultValue && !selectedRange || defaultValue && selectedRange && defaultValue.label === selectedRange.label && defaultValue.label !== CUSTOM_CALENDAR_ID || defaultValue && selectedRange && defaultValue.label === selectedRange.label && defaultValue.label === CUSTOM_CALENDAR_ID && customDate.from && customDate.to && new Date(customDate.from).toISOString() === defaultValue.from.toISOString() && new Date(customDate.to).toISOString() === defaultValue.to.toISOString();
@@ -18,7 +18,7 @@ export const FiltersBarPeriodPicker = ({ props, hasApplyButton, className, useSi
18
18
  const [selectedRange, setSelectedRange] = useState(getSelectedRangeFromValue(optionsMap, state));
19
19
  const filterBarLabelledId = useId();
20
20
  const [prevSelection, setPrevSelection] = useState(getSelectedRangeFromValue(optionsMap, state));
21
- const datesValidation = useCallback(val => isValidDateFn(props.allowUnsetValue || false)(val), [props.allowUnsetValue]);
21
+ const datesValidation = useMemo(() => isValidDateFn(props.allowUnsetValue || false), [props.allowUnsetValue]);
22
22
  const isDatesValid = useRef(datesValidation(state));
23
23
  const getCustomRange = useCallback(() => ({ from: (prevSelection === null || prevSelection === void 0 ? void 0 : prevSelection.from) || new Date(), to: (prevSelection === null || prevSelection === void 0 ? void 0 : prevSelection.to) || new Date() }), [prevSelection]);
24
24
  const options = useMemo(() => getRangeOptionsArray(optionsArg, translate, toLocalDateTime, weekStartsOnSunday ? "Sunday" : "Monday", toReverseOffsetDateTime, withCalendar || false, prevSelection && prevSelection.label === CUSTOM_CALENDAR_ID, prevSelection ? getCustomRange : undefined), [optionsArg, translate, toLocalDateTime, weekStartsOnSunday, toReverseOffsetDateTime, withCalendar, prevSelection, getCustomRange]);
@@ -295,13 +295,8 @@ export const GroupsFilterRaw = props => {
295
295
  const prevSearchField = useRef("");
296
296
  const groupsFilterId = useId();
297
297
  const popupId = useId();
298
+ const isDataLoadedRef = useRef(false);
298
299
  const blocksMap = useMemo(() => [["builtInGroups", "userGroups"], ["advancedGroups", "builtInGroups", "userGroups"], ["builtInGroups", "userGroups"]], []);
299
- const onOptionsToggle = useCallback(() => {
300
- dispatchUiState({
301
- type: UiStateActionType.ToggleOpen,
302
- payload: undefined
303
- });
304
- }, []);
305
300
  const handleSetStep = useCallback(newStep => {
306
301
  var _a;
307
302
  uiState.step !== FilterMenuStep.CurrentlySelected && dispatchUiState({
@@ -551,6 +546,7 @@ export const GroupsFilterRaw = props => {
551
546
  return [];
552
547
  }), [dataLoader, errorHandler]);
553
548
  const loadData = useCallback(() => {
549
+ isDataLoadedRef.current = true;
554
550
  dispatchUiState({
555
551
  type: UiStateActionType.SetLoadWithError,
556
552
  payload: {
@@ -579,12 +575,32 @@ export const GroupsFilterRaw = props => {
579
575
  isLoading: false
580
576
  }
581
577
  });
578
+ isDataLoadedRef.current = false;
582
579
  errorHandler(e);
583
580
  });
584
581
  }, [dataLoader, errorHandler]);
585
582
  useEffect(() => {
583
+ if (isDataLoadedRef.current) {
584
+ return;
585
+ }
586
586
  loadData();
587
587
  }, [loadData]);
588
+ const onOptionsToggle = useCallback(() => {
589
+ const willBeOpen = !uiState.isOpen;
590
+ dispatchUiState({
591
+ type: UiStateActionType.ToggleOpen,
592
+ payload: undefined
593
+ });
594
+ if (willBeOpen && !isDataLoadedRef.current && !uiState.isLoading) {
595
+ loadData();
596
+ }
597
+ }, [uiState.isOpen, uiState.isLoading, loadData]);
598
+ const isEmptyMap = dataItems.length === 0;
599
+ useEffect(() => {
600
+ if (isEmptyMap && uiState.isOpen && !uiState.isLoading && !uiState.hasError) {
601
+ loadData();
602
+ }
603
+ }, [uiState.isOpen, isEmptyMap, uiState.isLoading, uiState.hasError, loadData]);
588
604
  useEffect(() => {
589
605
  const step = uiState.step;
590
606
  if (step !== FilterMenuStep.CurrentlySelected) {
@@ -825,12 +841,6 @@ export const GroupsFilterRaw = props => {
825
841
  children: translate("Clear")
826
842
  })]
827
843
  }), [handleApply, handleCancel, handleReset, isApplyDisabled, translate]);
828
- const isEmptyMap = dataItems.length === 0;
829
- useEffect(() => {
830
- if (isEmptyMap && uiState.isOpen && !uiState.isLoading && !uiState.hasError) {
831
- loadData();
832
- }
833
- }, [uiState.isOpen, isEmptyMap, uiState.isLoading, uiState.hasError, loadData]);
834
844
  const memoizedMobileView = useMemo(() => _jsxs(MobileSheet, {
835
845
  label: translate("Organization groups filter"),
836
846
  triggerRef: triggerRef,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geotab/zenith",
3
- "version": "3.6.0-beta.4",
3
+ "version": "3.6.0-beta.6",
4
4
  "description": "Zenith components library on React",
5
5
  "main": "dist/index.js",
6
6
  "types": "esm/index.d.ts",
@@ -98,12 +98,6 @@
98
98
  "react": "^19.2.0",
99
99
  "react-dom": "^19.2.0"
100
100
  },
101
- "overrides": {
102
- "ajv": "^8.18.0",
103
- "minimatch": "^10.2.2",
104
- "glob": "^13.0.6",
105
- "rimraf": "^6.1.3"
106
- },
107
101
  "files": [
108
102
  "./dist/",
109
103
  "./esm"