@websolutespa/bom-mixer-hooks 1.2.0 → 1.2.1

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/CHANGELOG.md CHANGED
@@ -1,49 +1,56 @@
1
- # @websolutespa/bom-mixer-hooks
2
-
3
- ## 1.2.0
4
-
5
- ### Minor Changes
6
-
7
- - Updating: next 13.
8
-
9
- ## 1.1.0
10
-
11
- ### Minor Changes
12
-
13
- - Modified: useHttp, useApi.
14
-
15
- ## 1.0.0
16
-
17
- ### Minor Changes
18
-
19
- - Added: useScrolled.
20
-
21
- ## 0.2.2
22
-
23
- ### Patch Changes
24
-
25
- - Modified: useBreakpoint theme mediaQuery.
26
-
27
- ## 0.2.1
28
-
29
- ### Patch Changes
30
-
31
- - Added: source files.
32
-
33
- ## 0.2.0
34
-
35
- ### Minor Changes
36
-
37
- - Added: splat routes.
38
-
39
- ## 0.1.0
40
-
41
- ### Minor Changes
42
-
43
- - Added: @websolutespa/bom-core.
44
-
45
- ## 0.0.2
46
-
47
- ### Patch Changes
48
-
49
- - Added: first release.
1
+ # @websolutespa/bom-mixer-hooks
2
+
3
+ ## 1.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Added: LabelService.
8
+ - Modified: useLabels, useScrollTo.
9
+
10
+ ## 1.2.0
11
+
12
+ ### Minor Changes
13
+
14
+ - Updating: next 13.
15
+
16
+ ## 1.1.0
17
+
18
+ ### Minor Changes
19
+
20
+ - Modified: useHttp, useApi.
21
+
22
+ ## 1.0.0
23
+
24
+ ### Minor Changes
25
+
26
+ - Added: useScrolled.
27
+
28
+ ## 0.2.2
29
+
30
+ ### Patch Changes
31
+
32
+ - Modified: useBreakpoint theme mediaQuery.
33
+
34
+ ## 0.2.1
35
+
36
+ ### Patch Changes
37
+
38
+ - Added: source files.
39
+
40
+ ## 0.2.0
41
+
42
+ ### Minor Changes
43
+
44
+ - Added: splat routes.
45
+
46
+ ## 0.1.0
47
+
48
+ ### Minor Changes
49
+
50
+ - Added: @websolutespa/bom-core.
51
+
52
+ ## 0.0.2
53
+
54
+ ### Patch Changes
55
+
56
+ - Added: first release.
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import * as zustand_middleware from 'zustand/middleware';
6
6
  import { StateStorage } from 'zustand/middleware';
7
7
  import * as zustand from 'zustand';
8
- import { ISchema, IEquatable, ILayout, IPage } from '@websolutespa/bom-core';
8
+ import { ISchema, IEquatable, ILabel, ILocalizable, ILayout, IPage } from '@websolutespa/bom-core';
9
9
  import { ICartItem, ICartAddItem, IAddressOptions, ICheckoutPartial, IFeatureType, IUser } from '@websolutespa/bom-mixer-models';
10
10
  import { NextRouter } from 'next/router';
11
11
 
@@ -371,16 +371,19 @@ type KeyboardResult = {
371
371
  type UseKeyboardHandler = (event: React__default.KeyboardEvent | KeyboardEvent) => void;
372
372
  type UseKeyboard = (handler: UseKeyboardHandler, keyBindings: Array<number> | number, options?: KeyboardOptions) => KeyboardResult;
373
373
 
374
- type ILabelContext = (key: string, params?: {
375
- [key: string]: any;
376
- }) => string;
374
+ type ILabelContext = (key: string, params?: Record<string, any>) => string;
377
375
  declare const useLabel: () => ILabelContext;
378
376
  declare function LabelProvider({ children }: {
379
377
  children?: React__default.ReactNode;
380
378
  }): react_jsx_runtime.JSX.Element;
381
- declare function parseParams(label: string, params: {
382
- [key: string]: any;
383
- }): string;
379
+ declare class LabelService {
380
+ labels: ILabel[];
381
+ dictionary: Record<string, ILocalizable | undefined>;
382
+ constructor(labels: ILabel[]);
383
+ getLabel(key: string, params?: Record<string, any>): string;
384
+ }
385
+ declare function parseLabel(dictionary: Record<string, ILocalizable | undefined>, key: string, params?: Record<string, any>): string;
386
+ declare function parseParams(label: string, params: Record<string, any>): string;
384
387
 
385
388
  type ILayoutContext = ILayout;
386
389
  declare const useLayout: () => ILayout;
@@ -451,7 +454,7 @@ type Scroll = {
451
454
  };
452
455
  declare function useScroll(): Scroll;
453
456
 
454
- declare function useScrollTo(): (event: React.MouseEvent<HTMLElement>) => void;
457
+ declare function useScrollTo(offset?: number): (event: React.MouseEvent<HTMLElement>) => void;
455
458
  declare function scrollToSelector(selector?: string, offset?: number): void;
456
459
  declare function scrollToRelativeY(y?: number, offset?: number): void;
457
460
  declare function scrollToY(y?: number): void;
@@ -552,4 +555,4 @@ type WindowSize = {
552
555
  };
553
556
  declare function useWindowSize(): WindowSize;
554
557
 
555
- export { BodyScrollOptions, CartContext, CartProvider, CheckoutContext, CheckoutProvider, ClickOutGetContainer, CurrentStateType, ElementStackItem, Filter, FilterMode, FilterParams, FilterValues, GeoLocationSensorState, IFilter, IFilterOption, IGeolocationPositionError, ILabelContext, ILayoutContext, IPageContext, IPaginationInfo, IParams, IParamsEncoded, IUseSearchParamsEncodedResult, IUseSearchParamsResult, IUseSearchParamsValueResult, KeyCode, KeyMod, KeyboardOptions, KeyboardResult, LabelProvider, LayoutProvider, PageProvider, SSRState, SizeResult, SizeType, Sorting, UIReducer, UIValue, UseFiltersResultType, UseKeyboard, UseKeyboardHandler, createElementWithId, createGenericContext, decode, detectIsBrowser, filtersToParams, getCurrentPosition, getFilteredItems, getFilters, getOwnerPaddingRight, getOwnerScrollbarWidth, getPagedItems, getRealSize, getSearchParams, getSearchParamsEncoded, getUID, hasGeolocation, isBrowser, parseParams, pushSearchParams, pushSearchParamsEncoded, replaceSearchParams, replaceSearchParamsEncoded, replaceSearchParamsEncodedSilently, replaceSearchParamsSilently, scrollToRelativeY, scrollToSelector, scrollToY, setFilters, updateSearchParams, updateSearchParamsEncoded, useApi, useApiDelete, useApiFetch, useApiGet, useApiPatch, useApiPost, useApiPut, useBodyScroll, useBreakpoint, useCart, useCheckout, useClickAnyWhere, useClickOut, useCurrency, useCurrentState, useDateTimeFormat, useDebounce, useDebounceCallback, useDebugChangedProps, useDomObserver, useDrawer, useElementSize, useEventListener, useFilters, useGeolocation, useIdle, useInfiniteLoader, useIsomorphicLayoutEffect, useKeyboard, useLabel, useLayout, useModal, useMounted, useNumber, usePage, usePagination, usePortal, usePrevious, useRealSize, useResize, useSSR, useScroll, useScrollTo, useScrolled, useSearchParams, useSearchParamsEncoded, useSearchParamsValue, useSorting, useSwiperIndex, useSyncedRef, useUI, useUnit, useUnmountEffect, useUser, useWindowSize };
558
+ export { BodyScrollOptions, CartContext, CartProvider, CheckoutContext, CheckoutProvider, ClickOutGetContainer, CurrentStateType, ElementStackItem, Filter, FilterMode, FilterParams, FilterValues, GeoLocationSensorState, IFilter, IFilterOption, IGeolocationPositionError, ILabelContext, ILayoutContext, IPageContext, IPaginationInfo, IParams, IParamsEncoded, IUseSearchParamsEncodedResult, IUseSearchParamsResult, IUseSearchParamsValueResult, KeyCode, KeyMod, KeyboardOptions, KeyboardResult, LabelProvider, LabelService, LayoutProvider, PageProvider, SSRState, SizeResult, SizeType, Sorting, UIReducer, UIValue, UseFiltersResultType, UseKeyboard, UseKeyboardHandler, createElementWithId, createGenericContext, decode, detectIsBrowser, filtersToParams, getCurrentPosition, getFilteredItems, getFilters, getOwnerPaddingRight, getOwnerScrollbarWidth, getPagedItems, getRealSize, getSearchParams, getSearchParamsEncoded, getUID, hasGeolocation, isBrowser, parseLabel, parseParams, pushSearchParams, pushSearchParamsEncoded, replaceSearchParams, replaceSearchParamsEncoded, replaceSearchParamsEncodedSilently, replaceSearchParamsSilently, scrollToRelativeY, scrollToSelector, scrollToY, setFilters, updateSearchParams, updateSearchParamsEncoded, useApi, useApiDelete, useApiFetch, useApiGet, useApiPatch, useApiPost, useApiPut, useBodyScroll, useBreakpoint, useCart, useCheckout, useClickAnyWhere, useClickOut, useCurrency, useCurrentState, useDateTimeFormat, useDebounce, useDebounceCallback, useDebugChangedProps, useDomObserver, useDrawer, useElementSize, useEventListener, useFilters, useGeolocation, useIdle, useInfiniteLoader, useIsomorphicLayoutEffect, useKeyboard, useLabel, useLayout, useModal, useMounted, useNumber, usePage, usePagination, usePortal, usePrevious, useRealSize, useResize, useSSR, useScroll, useScrollTo, useScrolled, useSearchParams, useSearchParamsEncoded, useSearchParamsValue, useSorting, useSwiperIndex, useSyncedRef, useUI, useUnit, useUnmountEffect, useUser, useWindowSize };
package/dist/index.js CHANGED
@@ -78,6 +78,7 @@ __export(src_exports, {
78
78
  KeyCode: () => KeyCode,
79
79
  KeyMod: () => KeyMod,
80
80
  LabelProvider: () => LabelProvider,
81
+ LabelService: () => LabelService,
81
82
  LayoutProvider: () => LayoutProvider,
82
83
  PageProvider: () => PageProvider,
83
84
  createElementWithId: () => createElementWithId,
@@ -97,6 +98,7 @@ __export(src_exports, {
97
98
  getUID: () => getUID,
98
99
  hasGeolocation: () => hasGeolocation,
99
100
  isBrowser: () => isBrowser,
101
+ parseLabel: () => parseLabel,
100
102
  parseParams: () => parseParams,
101
103
  pushSearchParams: () => pushSearchParams,
102
104
  pushSearchParamsEncoded: () => pushSearchParamsEncoded,
@@ -1346,16 +1348,28 @@ var useKeyboard = (handler, keyBindings, options = {}) => {
1346
1348
  var import_jsx_runtime4 = require("react/jsx-runtime");
1347
1349
  var [useLabel, LabelContextProvider] = createGenericContext();
1348
1350
  function LabelProvider({ children }) {
1349
- const { locale, labels } = useLayout();
1350
- const dictionary = Object.fromEntries(labels.map((l) => [l.id, l.text]));
1351
- const context = (key, params) => {
1352
- const label = dictionary[key] != null ? dictionary[key] : key;
1353
- if (params) {
1354
- return parseParams(label, params);
1355
- }
1356
- return label;
1351
+ const { labels } = useLayout();
1352
+ const labelService = new LabelService(labels);
1353
+ const getLabel = (key, params) => {
1354
+ return labelService.getLabel(key, params);
1357
1355
  };
1358
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LabelContextProvider, { value: context, children });
1356
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LabelContextProvider, { value: getLabel, children });
1357
+ }
1358
+ var LabelService = class {
1359
+ constructor(labels) {
1360
+ this.labels = labels;
1361
+ this.dictionary = Object.fromEntries(labels.map((l) => [l.id, l.text]));
1362
+ }
1363
+ getLabel(key, params) {
1364
+ return parseLabel(this.dictionary, key, params);
1365
+ }
1366
+ };
1367
+ function parseLabel(dictionary, key, params) {
1368
+ const label = dictionary[key] != null ? dictionary[key] : key;
1369
+ if (params) {
1370
+ return parseParams(label, params);
1371
+ }
1372
+ return label;
1359
1373
  }
1360
1374
  function parseParams(label, params) {
1361
1375
  const TEMPLATE_REGEXP = /@(\w+)/g;
@@ -1539,12 +1553,12 @@ function useScroll() {
1539
1553
 
1540
1554
  // src/useScrollTo/useScrollTo.ts
1541
1555
  var import_framer_motion = require("framer-motion");
1542
- function useScrollTo() {
1556
+ function useScrollTo(offset = 0) {
1543
1557
  const scrollToHash = (event) => {
1544
1558
  const href = event.currentTarget.getAttribute("href");
1545
1559
  if (href && href.indexOf("#") !== -1) {
1546
1560
  const hashId = `#${href.split("#")[1]}`;
1547
- scrollToSelector(hashId);
1561
+ scrollToSelector(hashId, offset);
1548
1562
  }
1549
1563
  };
1550
1564
  return scrollToHash;
@@ -1893,6 +1907,7 @@ var useUser = (0, import_zustand4.create)((set) => ({
1893
1907
  KeyCode,
1894
1908
  KeyMod,
1895
1909
  LabelProvider,
1910
+ LabelService,
1896
1911
  LayoutProvider,
1897
1912
  PageProvider,
1898
1913
  createElementWithId,
@@ -1912,6 +1927,7 @@ var useUser = (0, import_zustand4.create)((set) => ({
1912
1927
  getUID,
1913
1928
  hasGeolocation,
1914
1929
  isBrowser,
1930
+ parseLabel,
1915
1931
  parseParams,
1916
1932
  pushSearchParams,
1917
1933
  pushSearchParamsEncoded,
package/dist/index.mjs CHANGED
@@ -1228,16 +1228,28 @@ var useKeyboard = (handler, keyBindings, options = {}) => {
1228
1228
  import { jsx as jsx4 } from "react/jsx-runtime";
1229
1229
  var [useLabel, LabelContextProvider] = createGenericContext();
1230
1230
  function LabelProvider({ children }) {
1231
- const { locale, labels } = useLayout();
1232
- const dictionary = Object.fromEntries(labels.map((l) => [l.id, l.text]));
1233
- const context = (key, params) => {
1234
- const label = dictionary[key] != null ? dictionary[key] : key;
1235
- if (params) {
1236
- return parseParams(label, params);
1237
- }
1238
- return label;
1231
+ const { labels } = useLayout();
1232
+ const labelService = new LabelService(labels);
1233
+ const getLabel = (key, params) => {
1234
+ return labelService.getLabel(key, params);
1239
1235
  };
1240
- return /* @__PURE__ */ jsx4(LabelContextProvider, { value: context, children });
1236
+ return /* @__PURE__ */ jsx4(LabelContextProvider, { value: getLabel, children });
1237
+ }
1238
+ var LabelService = class {
1239
+ constructor(labels) {
1240
+ this.labels = labels;
1241
+ this.dictionary = Object.fromEntries(labels.map((l) => [l.id, l.text]));
1242
+ }
1243
+ getLabel(key, params) {
1244
+ return parseLabel(this.dictionary, key, params);
1245
+ }
1246
+ };
1247
+ function parseLabel(dictionary, key, params) {
1248
+ const label = dictionary[key] != null ? dictionary[key] : key;
1249
+ if (params) {
1250
+ return parseParams(label, params);
1251
+ }
1252
+ return label;
1241
1253
  }
1242
1254
  function parseParams(label, params) {
1243
1255
  const TEMPLATE_REGEXP = /@(\w+)/g;
@@ -1421,12 +1433,12 @@ function useScroll() {
1421
1433
 
1422
1434
  // src/useScrollTo/useScrollTo.ts
1423
1435
  import { animate } from "framer-motion";
1424
- function useScrollTo() {
1436
+ function useScrollTo(offset = 0) {
1425
1437
  const scrollToHash = (event) => {
1426
1438
  const href = event.currentTarget.getAttribute("href");
1427
1439
  if (href && href.indexOf("#") !== -1) {
1428
1440
  const hashId = `#${href.split("#")[1]}`;
1429
- scrollToSelector(hashId);
1441
+ scrollToSelector(hashId, offset);
1430
1442
  }
1431
1443
  };
1432
1444
  return scrollToHash;
@@ -1774,6 +1786,7 @@ export {
1774
1786
  KeyCode,
1775
1787
  KeyMod,
1776
1788
  LabelProvider,
1789
+ LabelService,
1777
1790
  LayoutProvider,
1778
1791
  PageProvider,
1779
1792
  createElementWithId,
@@ -1793,6 +1806,7 @@ export {
1793
1806
  getUID,
1794
1807
  hasGeolocation,
1795
1808
  isBrowser,
1809
+ parseLabel,
1796
1810
  parseParams,
1797
1811
  pushSearchParams,
1798
1812
  pushSearchParamsEncoded,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websolutespa/bom-mixer-hooks",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Mixer Hooks module of the BOM Repository",
5
5
  "keywords": [
6
6
  "bom",
@@ -32,7 +32,7 @@
32
32
  "next": ">= 13.4.19",
33
33
  "react-dom": ">= 18.2.0",
34
34
  "react": ">= 18.2.0",
35
- "styled-components": ">= 5.3.11",
35
+ "styled-components": ">= 5.3.11 <6.x.x",
36
36
  "swiper": ">= 8.3.2",
37
37
  "zustand": ">= 4.4.0"
38
38
  },
@@ -29,7 +29,7 @@ describe('useDateTimeFormat', () => {
29
29
  const { result } = renderHook(() => useDateTimeFormat({
30
30
  year: 'numeric',
31
31
  month: 'short',
32
- day: 'numeric'
32
+ day: 'numeric',
33
33
  }), { wrapper });
34
34
  const formatted = result.current(new Date(2023, 0, 19));
35
35
  expect(formatted).toEqual('Jan 19, 2023');
@@ -39,7 +39,7 @@ describe('useDateTimeFormat', () => {
39
39
  const { result } = renderHook(() => useDateTimeFormat({
40
40
  year: 'numeric',
41
41
  month: 'short',
42
- day: 'numeric'
42
+ day: 'numeric',
43
43
  }), { wrapper });
44
44
  const formatted = result.current('2023/1/19');
45
45
  expect(formatted).toEqual('Jan 19, 2023');
@@ -5,7 +5,7 @@ export function useDateTimeFormat(
5
5
  // weekday: 'long',
6
6
  year: 'numeric',
7
7
  month: 'numeric',
8
- day: 'numeric'
8
+ day: 'numeric',
9
9
  },
10
10
  locale?: string
11
11
  ): (value: Date | string) => string {
@@ -5,16 +5,16 @@ import { useElementSize } from './useElementSize';
5
5
  const setupHook = () => renderHook(() => useElementSize());
6
6
  const originalOffsetHeight = Object.getOwnPropertyDescriptor(
7
7
  HTMLElement.prototype,
8
- 'offsetHeight',
8
+ 'offsetHeight'
9
9
  ) as PropertyDescriptor;
10
10
  const originalOffsetWidth = Object.getOwnPropertyDescriptor(
11
11
  HTMLElement.prototype,
12
- 'offsetWidth',
12
+ 'offsetWidth'
13
13
  ) as PropertyDescriptor;
14
14
  const resizeElement = (
15
15
  node: HTMLElement,
16
16
  dimension: 'width' | 'height',
17
- value: number,
17
+ value: number
18
18
  ): void => {
19
19
  if (dimension === 'height') {
20
20
  return void Object.defineProperty(node, 'offsetHeight', {
@@ -37,12 +37,12 @@ describe('useElementSize', () => {
37
37
  Object.defineProperty(
38
38
  HTMLElement.prototype,
39
39
  'offsetHeight',
40
- originalOffsetHeight,
40
+ originalOffsetHeight
41
41
  );
42
42
  Object.defineProperty(
43
43
  HTMLElement.prototype,
44
44
  'offsetWidth',
45
- originalOffsetWidth,
45
+ originalOffsetWidth
46
46
  );
47
47
  });
48
48
 
@@ -26,7 +26,7 @@ const docRef = { current: window.document };
26
26
  const docAddEventListenerSpy = jest.spyOn(docRef.current, 'addEventListener');
27
27
  const docRemoveEventListenerSpy = jest.spyOn(
28
28
  docRef.current,
29
- 'removeEventListener',
29
+ 'removeEventListener'
30
30
  );
31
31
 
32
32
  describe('useEventListener', () => {
@@ -42,12 +42,12 @@ describe('useEventListener', () => {
42
42
  expect(windowAddEventListenerSpy).toHaveBeenCalledWith(
43
43
  eventName,
44
44
  expect.any(Function),
45
- options,
45
+ options
46
46
  );
47
47
  unmount();
48
48
  expect(windowRemoveEventListenerSpy).toHaveBeenCalledWith(
49
49
  eventName,
50
- expect.any(Function),
50
+ expect.any(Function)
51
51
  );
52
52
  });
53
53
 
@@ -56,18 +56,18 @@ describe('useEventListener', () => {
56
56
  const handler = jest.fn();
57
57
  const options = undefined;
58
58
  const { unmount } = renderHook(() =>
59
- useEventListener(eventName, handler, ref, options),
59
+ useEventListener(eventName, handler, ref, options)
60
60
  );
61
61
  expect(refAddEventListenerSpy).toHaveBeenCalledTimes(1);
62
62
  expect(refAddEventListenerSpy).toHaveBeenCalledWith(
63
63
  eventName,
64
64
  expect.any(Function),
65
- options,
65
+ options
66
66
  );
67
67
  unmount();
68
68
  expect(refRemoveEventListenerSpy).toHaveBeenCalledWith(
69
69
  eventName,
70
- expect.any(Function),
70
+ expect.any(Function)
71
71
  );
72
72
  });
73
73
 
@@ -76,18 +76,18 @@ describe('useEventListener', () => {
76
76
  const handler = jest.fn();
77
77
  const options = undefined;
78
78
  const { unmount } = renderHook(() =>
79
- useEventListener(eventName, handler, docRef, options),
79
+ useEventListener(eventName, handler, docRef, options)
80
80
  );
81
81
  expect(docAddEventListenerSpy).toHaveBeenCalledTimes(1);
82
82
  expect(docAddEventListenerSpy).toHaveBeenCalledWith(
83
83
  eventName,
84
84
  expect.any(Function),
85
- options,
85
+ options
86
86
  );
87
87
  unmount();
88
88
  expect(docRemoveEventListenerSpy).toHaveBeenCalledWith(
89
89
  eventName,
90
- expect.any(Function),
90
+ expect.any(Function)
91
91
  );
92
92
  });
93
93
 
@@ -103,7 +103,7 @@ describe('useEventListener', () => {
103
103
  expect(windowAddEventListenerSpy).toHaveBeenCalledWith(
104
104
  eventName,
105
105
  expect.any(Function),
106
- options,
106
+ options
107
107
  );
108
108
  });
109
109
 
@@ -19,7 +19,7 @@ describe('useFilters', () => {
19
19
  features: [{
20
20
  id: 1,
21
21
  title: 'feature',
22
- }]
22
+ }],
23
23
  }];
24
24
 
25
25
  const filterItem = jest.fn((key: string, item: Item, value: IEquatable) => {
@@ -18,8 +18,8 @@ describe('useGeolocation', () => {
18
18
  getCurrentPosition.mockImplementationOnce((success: (result: any) => Promise<any>) => Promise.resolve(success({
19
19
  coords: {
20
20
  latitude: 50.0,
21
- longitude: 40.0
22
- }
21
+ longitude: 40.0,
22
+ },
23
23
  })));
24
24
  const { result } = renderHook(() => useGeolocation());
25
25
  expect(result.current.latitude).toBe(50.0);
@@ -1,5 +1,5 @@
1
1
  import { fireEvent, render, renderHook, screen } from '@testing-library/react';
2
- import { KeyboardResult, KeyCode, KeyMod, useKeyboard } from './useKeyboard';
2
+ import { KeyCode, KeyMod, KeyboardResult, useKeyboard } from './useKeyboard';
3
3
 
4
4
  describe('useKeyboard', () => {
5
5
  it('should work correctly', () => {
@@ -46,19 +46,19 @@ describe('useKeyboard', () => {
46
46
  it('should work with each command', () => {
47
47
  const handler = jest.fn().mockImplementation(() => { });
48
48
  renderHook(() =>
49
- useKeyboard(handler, [KeyCode.KEY_A, KeyMod.Alt, KeyMod.CtrlCmd, KeyMod.WinCtrl]),
49
+ useKeyboard(handler, [KeyCode.KEY_A, KeyMod.Alt, KeyMod.CtrlCmd, KeyMod.WinCtrl])
50
50
  );
51
51
  document.dispatchEvent(
52
52
  new KeyboardEvent('keydown', {
53
53
  keyCode: KeyCode.KEY_A,
54
- }),
54
+ })
55
55
  );
56
56
  expect(handler).not.toBeCalled();
57
57
  document.dispatchEvent(
58
58
  new KeyboardEvent('keydown', {
59
59
  keyCode: KeyCode.KEY_A,
60
60
  altKey: true,
61
- }),
61
+ })
62
62
  );
63
63
  expect(handler).not.toBeCalled();
64
64
  document.dispatchEvent(
@@ -66,7 +66,7 @@ describe('useKeyboard', () => {
66
66
  keyCode: KeyCode.KEY_A,
67
67
  altKey: true,
68
68
  ctrlKey: true,
69
- }),
69
+ })
70
70
  );
71
71
  expect(handler).not.toBeCalled();
72
72
  document.dispatchEvent(
@@ -75,7 +75,7 @@ describe('useKeyboard', () => {
75
75
  altKey: true,
76
76
  ctrlKey: true,
77
77
  metaKey: true,
78
- }),
78
+ })
79
79
  );
80
80
  expect(handler).toBeCalledTimes(1);
81
81
  });
@@ -103,12 +103,12 @@ describe('useKeyboard', () => {
103
103
  const handler = jest.fn().mockImplementation(() => { });
104
104
  const nativeHandler = jest.fn().mockImplementation(() => { });
105
105
  const { result } = renderHook<KeyboardResult, {}>(() =>
106
- useKeyboard(handler, KeyCode.Escape),
106
+ useKeyboard(handler, KeyCode.Escape)
107
107
  );
108
108
  const { container } = render(
109
109
  <div onKeyDown={nativeHandler} >
110
110
  <span data-testid="inner" {...result.current.bindings} />
111
- </div>,
111
+ </div>
112
112
  );
113
113
  const inner = await screen.findByTestId('inner');
114
114
  fireEvent.keyUp(inner, {
@@ -133,7 +133,7 @@ describe('useKeyboard', () => {
133
133
  const { container } = render(
134
134
  <div onKeyDown={nativeHandler} >
135
135
  <span data-testid="inner" {...result.current.bindings} />
136
- </div>,
136
+ </div>
137
137
  );
138
138
  const inner = await screen.findByTestId('inner');
139
139
  expect(nativeHandler).not.toBeCalled();
@@ -147,12 +147,12 @@ describe('useKeyboard', () => {
147
147
  it('should trigger capture event', async () => {
148
148
  const handler = jest.fn().mockImplementation(() => { });
149
149
  const { result } = renderHook<KeyboardResult, {}>(() =>
150
- useKeyboard(handler, KeyCode.Escape, { capture: true, disableGlobalEvent: true }),
150
+ useKeyboard(handler, KeyCode.Escape, { capture: true, disableGlobalEvent: true })
151
151
  );
152
152
  const { container } = render(
153
153
  <div onKeyDownCapture={result.current.bindings.onKeyDownCapture} >
154
154
  <span data-testid="inner" />
155
- </div>,
155
+ </div>
156
156
  );
157
157
  const inner = await screen.findByTestId('inner');
158
158
  fireEvent.keyDown(inner, {
@@ -43,7 +43,7 @@ export const useKeyboard: UseKeyboard = (handler, keyBindings, options = {}) =>
43
43
 
44
44
  const elementBindingHandler = (
45
45
  elementEventType: 'keydown' | 'keypress' | 'keyup',
46
- isCapture: boolean = false,
46
+ isCapture: boolean = false
47
47
  ) => {
48
48
  if (elementEventType !== event) return () => { };
49
49
  if (isCapture !== capture) return () => { };
@@ -61,7 +61,7 @@ export const useKeyboard: UseKeyboard = (handler, keyBindings, options = {}) =>
61
61
  };
62
62
  };
63
63
 
64
- export { KeyMod, KeyCode };
64
+ export { KeyCode, KeyMod };
65
65
 
66
66
  export type KeyboardOptions = {
67
67
  disableGlobalEvent?: boolean
@@ -1,37 +1,47 @@
1
+ import { ILabel, ILocalizable } from '@websolutespa/bom-core';
1
2
  import React from 'react';
2
3
  import { createGenericContext } from '../useGenericContext/useGenericContext';
3
4
  import { useLayout } from '../useLayout/useLayout';
4
5
 
5
- export type ILabelContext = (key: string, params?: { [key: string]: any }) => string;
6
+ export type ILabelContext = (key: string, params?: Record<string, any>) => string;
6
7
 
7
8
  const [useLabel, LabelContextProvider] = createGenericContext<ILabelContext>();
8
9
 
9
10
  function LabelProvider({ children }: { children?: React.ReactNode }) {
10
-
11
- // const { locale, labels } = useLayout() || { locale: '*', labels: [] };
12
- const { locale, labels } = useLayout();
13
-
14
- // console.log('LabelProvider', locale);
15
-
16
- const dictionary = Object.fromEntries(labels.map(l => [l.id, l.text]));
17
-
18
- const context = (key: string, params?: { [key: string]: any }): string => {
19
- const label = (dictionary[key] != null ? dictionary[key] : key) as string;
20
- if (params) {
21
- return parseParams(label, params);
22
- }
23
- return label;
11
+ const { labels } = useLayout();
12
+ // console.log('LabelProvider', labels);
13
+ const labelService = new LabelService(labels);
14
+ const getLabel = (key: string, params?: Record<string, any>): string => {
15
+ return labelService.getLabel(key, params);
24
16
  };
25
-
26
- // console.log('LabelProvider.context', context);
27
17
  return (
28
- <LabelContextProvider value={context}>
18
+ <LabelContextProvider value={getLabel}>
29
19
  {children}
30
20
  </LabelContextProvider>
31
21
  );
32
22
  }
33
23
 
34
- function parseParams(label: string, params: { [key: string]: any }): string {
24
+ class LabelService {
25
+ labels: ILabel[];
26
+ dictionary: Record<string, ILocalizable | undefined>;
27
+ constructor(labels: ILabel[]) {
28
+ this.labels = labels;
29
+ this.dictionary = Object.fromEntries(labels.map(l => [l.id, l.text]));
30
+ }
31
+ getLabel(key: string, params?: Record<string, any>): string {
32
+ return parseLabel(this.dictionary, key, params);
33
+ }
34
+ }
35
+
36
+ function parseLabel(dictionary: Record<string, ILocalizable | undefined>, key: string, params?: Record<string, any>): string {
37
+ const label = (dictionary[key] != null ? dictionary[key] : key) as string;
38
+ if (params) {
39
+ return parseParams(label, params);
40
+ }
41
+ return label;
42
+ }
43
+
44
+ function parseParams(label: string, params: Record<string, any>): string {
35
45
  const TEMPLATE_REGEXP: RegExp = /@(\w+)/g;
36
46
  return label.replace(TEMPLATE_REGEXP, (text: string, key: string) => {
37
47
  const replacer: unknown = params[key];
@@ -39,5 +49,5 @@ function parseParams(label: string, params: { [key: string]: any }): string {
39
49
  });
40
50
  }
41
51
 
42
- export { useLabel, LabelProvider, parseParams };
52
+ export { LabelProvider, LabelService, parseLabel, parseParams, useLabel };
43
53
 
@@ -28,7 +28,7 @@ describe('useNumber', () => {
28
28
  test('should return formatted value', () => {
29
29
  const { result } = renderHook(() => useNumber({
30
30
  minimumFractionDigits: 2,
31
- maximumFractionDigits: 2
31
+ maximumFractionDigits: 2,
32
32
  }), { wrapper });
33
33
  const formatted = result.current(1234.5678);
34
34
  expect(formatted).toEqual('1,234.57');
@@ -1,6 +1,6 @@
1
1
  import { animate } from 'framer-motion';
2
2
 
3
- export function useScrollTo(): (event: React.MouseEvent<HTMLElement>) => void {
3
+ export function useScrollTo(offset: number = 0): (event: React.MouseEvent<HTMLElement>) => void {
4
4
  // The handler to smoothly scroll the element into view
5
5
  const scrollToHash = (event: React.MouseEvent<HTMLElement>) => {
6
6
  const href = event.currentTarget.getAttribute('href');
@@ -9,7 +9,7 @@ export function useScrollTo(): (event: React.MouseEvent<HTMLElement>) => void {
9
9
  const hashId = `#${href.split('#')[1]}`;
10
10
  // console.log('hashId', hashId);
11
11
  // console.log('NavLink.onClick', event.currentTarget.getAttribute('href'), hashId);
12
- scrollToSelector(hashId);
12
+ scrollToSelector(hashId, offset);
13
13
  }
14
14
  };
15
15
  return scrollToHash;
@@ -36,6 +36,6 @@ export function scrollToY(y: number = 0) {
36
36
  const duration = Math.sqrt(Math.abs(to - from) / 4000);
37
37
  animate(from, to, {
38
38
  duration,
39
- onUpdate: v => window.scrollTo(0, v)
39
+ onUpdate: v => window.scrollTo(0, v),
40
40
  });
41
41
  }
@@ -52,7 +52,7 @@ describe('useSearchParams', () => {
52
52
  expect(handler).toBeCalledTimes(1);
53
53
  expect(handler).toBeCalledWith({
54
54
  pathname: '',
55
- query: { flag: '1' }
55
+ query: { flag: '1' },
56
56
  });
57
57
  });
58
58
 
@@ -51,7 +51,7 @@ describe('useSearchParamsEncoded', () => {
51
51
  expect(handler).toBeCalledTimes(1);
52
52
  expect(handler).toBeCalledWith({
53
53
  pathname: '',
54
- query: { params: 'eyJmbGFnIjoiMSJ9' }
54
+ query: { params: 'eyJmbGFnIjoiMSJ9' },
55
55
  });
56
56
  });
57
57