@synerise/ds-utils 1.6.0 → 1.7.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 +10 -0
- package/README.md +20 -4
- package/dist/doubleClickListener/doubleClickListener.d.ts +1 -1
- package/dist/doubleClickListener/doubleClickListener.js +8 -9
- package/dist/focusWithArrowKeys/focusWithArrowKeys.d.ts +1 -1
- package/dist/focusWithArrowKeys/focusWithArrowKeys.js +24 -22
- package/dist/getInitials/getInitials.js +7 -11
- package/dist/getPopupContainer/getPopupContainer.js +9 -5
- package/dist/getPopupContainer/index.js +5 -1
- package/dist/hexToRgba/hexToRgba.js +8 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.js +64 -27
- package/dist/modules.d.js +1 -0
- package/dist/modules.d.ts +1 -0
- package/dist/omitKeys/omitKeys.js +4 -6
- package/dist/regex/regex.js +3 -3
- package/dist/renderWithHighlight/renderWithHighlight.d.ts +1 -1
- package/dist/renderWithHighlight/renderWithHighlight.js +13 -20
- package/dist/selectColorByLetter/selectColorByLetter.js +17 -15
- package/dist/toCamelCase/toCamelCase.js +4 -14
- package/dist/types/types.d.ts +2 -2
- package/dist/types/types.js +1 -1
- package/dist/useBreakpoint/useBreakpoint.js +29 -28
- package/dist/useCombinedRefs/useCombinedRefs.d.ts +1 -1
- package/dist/useCombinedRefs/useCombinedRefs.js +9 -10
- package/dist/useDelimiterEscape/useDelimiterEscape.js +34 -62
- package/dist/useElementInView/useElementInView.d.ts +2 -2
- package/dist/useElementInView/useElementInView.js +16 -17
- package/dist/useIsMounted/useIsMounted.d.ts +1 -1
- package/dist/useIsMounted/useIsMounted.js +9 -6
- package/dist/useKeyboardShortcuts/useKeyboardShortcuts.js +11 -8
- package/dist/useLatestRef/index.js +4 -1
- package/dist/useLatestRef/useLatestRef.d.ts +1 -1
- package/dist/useLatestRef/useLatestRef.js +8 -5
- package/dist/useOnClickOutside/useOnClickOutside.d.ts +1 -1
- package/dist/useOnClickOutside/useOnClickOutside.js +19 -33
- package/dist/useOverscrollBlock/useOverscrollBlock.d.ts +1 -1
- package/dist/useOverscrollBlock/useOverscrollBlock.js +18 -16
- package/dist/usePrevious/usePrevious.js +6 -4
- package/dist/useResize/useResize.d.ts +1 -1
- package/dist/useResize/useResize.js +19 -25
- package/dist/useResizeObserver/useResizeObserver.d.ts +1 -1
- package/dist/useResizeObserver/useResizeObserver.js +16 -16
- package/dist/useResizeToFit/useResizeToFit.d.ts +1 -1
- package/dist/useResizeToFit/useResizeToFit.js +17 -14
- package/dist/useScrollContain/useScrollContain.d.ts +1 -1
- package/dist/useScrollContain/useScrollContain.js +13 -10
- package/dist/useSearchResults/index.js +8 -2
- package/dist/useSearchResults/search.utils.d.ts +1 -1
- package/dist/useSearchResults/search.utils.js +11 -13
- package/dist/useSearchResults/types.js +1 -1
- package/dist/useSearchResults/useSearchResults.d.ts +1 -1
- package/dist/useSearchResults/useSearchResults.js +29 -38
- package/dist/useStableId/useStableId.js +9 -11
- package/dist/useStickyScroll/useStickyScroll.d.ts +8 -0
- package/dist/useStickyScroll/useStickyScroll.js +59 -0
- package/dist/useTraceUpdate/index.js +10 -10
- package/package.json +4 -4
- package/dist/doubleClickListener/__specs__/doubleClickListener.spec.d.ts +0 -1
- package/dist/focusWithArrowKeys/__specs__/focusWithArrowKeys.spec.d.ts +0 -1
- package/dist/getInitials/__specs__/getInitials.spec.d.ts +0 -1
- package/dist/getPopupContainer/getPopupContainer.spec.d.ts +0 -1
- package/dist/regex/__specs__/regex.spec.d.ts +0 -1
- package/dist/selectColorByLetter/selectColorByLetter.spec.d.ts +0 -1
- package/dist/toCamelCase/__specs__/toCamelCase.spec.d.ts +0 -1
- package/dist/useDelimiterEscape/__specs__/useDelimiterEscape.spec.d.ts +0 -1
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
useEffect(
|
|
5
|
-
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
const useScrollContain = () => {
|
|
3
|
+
const elementRef = useRef(null);
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const blockWheel = (event) => {
|
|
6
6
|
event.stopPropagation();
|
|
7
7
|
event.preventDefault();
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
let element;
|
|
10
10
|
if (elementRef.current) {
|
|
11
11
|
element = elementRef.current;
|
|
12
|
-
element.addEventListener(
|
|
12
|
+
element.addEventListener("wheel", blockWheel);
|
|
13
13
|
}
|
|
14
|
-
return
|
|
15
|
-
element && element.removeEventListener(
|
|
14
|
+
return () => {
|
|
15
|
+
element && element.removeEventListener("wheel", blockWheel);
|
|
16
16
|
};
|
|
17
17
|
}, []);
|
|
18
18
|
return elementRef;
|
|
19
|
-
};
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
useScrollContain
|
|
22
|
+
};
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { getActiveTabGroup, getGroupName, isItemInGroup } from "./search.utils.js";
|
|
2
|
+
import { useSearchResults } from "./useSearchResults.js";
|
|
3
|
+
export {
|
|
4
|
+
getActiveTabGroup,
|
|
5
|
+
getGroupName,
|
|
6
|
+
isItemInGroup,
|
|
7
|
+
useSearchResults
|
|
8
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseGroupType } from './types';
|
|
2
2
|
export declare const isItemInGroup: <GroupType extends BaseGroupType<GroupType>>(groupId?: string | number, currentGroup?: GroupType) => boolean;
|
|
3
3
|
export declare const getActiveTabGroup: <GroupType extends BaseGroupType<GroupType>>(tabIndex: number, groups?: GroupType[]) => GroupType | undefined;
|
|
4
4
|
export declare const getGroupName: <GroupType extends BaseGroupType<GroupType>>(groupId: string | number | undefined, groups: BaseGroupType<GroupType>[]) => string | undefined;
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
const isItemInGroup = (groupId, currentGroup) => {
|
|
2
2
|
if (!currentGroup || !groupId) {
|
|
3
3
|
return true;
|
|
4
4
|
}
|
|
5
|
-
return currentGroup.subGroups ? (
|
|
6
|
-
return group.id === groupId;
|
|
7
|
-
})) > -1 : groupId === currentGroup.id;
|
|
5
|
+
return currentGroup.subGroups ? currentGroup?.subGroups.findIndex((group) => group.id === groupId) > -1 : groupId === currentGroup.id;
|
|
8
6
|
};
|
|
9
|
-
|
|
7
|
+
const getActiveTabGroup = (tabIndex, groups) => {
|
|
10
8
|
return groups && groups[tabIndex];
|
|
11
9
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
10
|
+
const getGroupName = (groupId, groups) => {
|
|
11
|
+
return groupId ? groups.flatMap((group) => group.subGroups ? group.subGroups : group).find((group) => group.id === groupId)?.name : void 0;
|
|
12
|
+
};
|
|
13
|
+
export {
|
|
14
|
+
getActiveTabGroup,
|
|
15
|
+
getGroupName,
|
|
16
|
+
isItemInGroup
|
|
17
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseGroupType, BaseItemType } from './types';
|
|
2
2
|
export declare const useSearchResults: <ItemType extends BaseItemType, GroupType extends BaseGroupType<GroupType>, GroupedListItemType>(items: ItemType[], groups: GroupType[], activeTab: number, groupByGroupName: (items: ItemType[], max?: number) => GroupedListItemType[], activeGroup?: GroupType, searchQuery?: string, maxSearchResultsInGroup?: number) => {
|
|
3
3
|
searchResults: GroupedListItemType[];
|
|
4
4
|
getActiveTabGroup: <GroupType_1 extends BaseGroupType<GroupType_1>>(tabIndex: number, groups?: GroupType_1[]) => GroupType_1 | undefined;
|
|
@@ -1,54 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return activeTab && !activeGroup ? Boolean((_getActiveTabGroup = getActiveTabGroup(activeTab, groups)) == null ? void 0 : _getActiveTabGroup.subGroups) : Boolean(activeTab === 0 && !activeGroup);
|
|
8
|
-
}, [activeTab, activeGroup, groups]);
|
|
9
|
-
var groupOrder = useMemo(function () {
|
|
10
|
-
return groups.flatMap(function (group) {
|
|
11
|
-
return group.subGroups ? group.subGroups.map(function (subgroup) {
|
|
12
|
-
return subgroup.id;
|
|
13
|
-
}) : group.id;
|
|
14
|
-
});
|
|
15
|
-
}, [groups]);
|
|
16
|
-
var searchResults = useMemo(function () {
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { getActiveTabGroup, isItemInGroup, getGroupName } from "./search.utils.js";
|
|
3
|
+
const useSearchResults = (items, groups, activeTab, groupByGroupName, activeGroup, searchQuery, maxSearchResultsInGroup) => {
|
|
4
|
+
const showGroupedResults = useMemo(() => activeTab && !activeGroup ? Boolean(getActiveTabGroup(activeTab, groups)?.subGroups) : Boolean(activeTab === 0 && !activeGroup), [activeTab, activeGroup, groups]);
|
|
5
|
+
const groupOrder = useMemo(() => groups.flatMap((group) => group.subGroups ? group.subGroups.map((subgroup) => subgroup.id) : group.id), [groups]);
|
|
6
|
+
const searchResults = useMemo(() => {
|
|
17
7
|
if (!searchQuery) {
|
|
18
8
|
return [];
|
|
19
9
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
for (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
const result = [];
|
|
11
|
+
const itemsNumber = items.length;
|
|
12
|
+
for (let i = 0; i < itemsNumber; i += 1) {
|
|
13
|
+
const item = items[i];
|
|
14
|
+
const itemInTab = !activeTab || isItemInGroup(item.groupId, getActiveTabGroup(activeTab, groups));
|
|
15
|
+
const itemInGroup = !activeGroup || item.groupId === activeGroup.id;
|
|
26
16
|
if (itemInGroup && itemInTab) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
var matching = !searchQuery || isMatchingName || isMatchingSubtitle;
|
|
17
|
+
const searchQueryInLowerCase = searchQuery.toLowerCase();
|
|
18
|
+
const isMatchingName = item.name?.toLowerCase().includes(searchQueryInLowerCase);
|
|
19
|
+
const isMatchingSubtitle = item.subtitle?.toLowerCase().includes(searchQueryInLowerCase);
|
|
20
|
+
const matching = !searchQuery || isMatchingName || isMatchingSubtitle;
|
|
32
21
|
if (matching) {
|
|
33
|
-
result.push(
|
|
34
|
-
groupName: showGroupedResults && item.groupId ? getGroupName(item.groupId, groups) :
|
|
35
|
-
|
|
22
|
+
result.push({
|
|
23
|
+
groupName: showGroupedResults && item.groupId ? getGroupName(item.groupId, groups) : void 0,
|
|
24
|
+
...item
|
|
25
|
+
});
|
|
36
26
|
}
|
|
37
27
|
}
|
|
38
28
|
}
|
|
39
29
|
if (groupOrder && groupOrder.length) {
|
|
40
|
-
result.sort(
|
|
41
|
-
return a.groupId !== undefined && b.groupId !== undefined ? groupOrder.indexOf(a.groupId) - groupOrder.indexOf(b.groupId) : 0;
|
|
42
|
-
});
|
|
30
|
+
result.sort((a, b) => a.groupId !== void 0 && b.groupId !== void 0 ? groupOrder.indexOf(a.groupId) - groupOrder.indexOf(b.groupId) : 0);
|
|
43
31
|
}
|
|
44
32
|
return result;
|
|
45
33
|
}, [activeGroup, activeTab, groupOrder, groups, items, searchQuery, showGroupedResults]);
|
|
46
|
-
|
|
47
|
-
return groupByGroupName(searchResults, showGroupedResults ? maxSearchResultsInGroup :
|
|
34
|
+
const groupedSearchResults = useMemo(() => {
|
|
35
|
+
return groupByGroupName(searchResults, showGroupedResults ? maxSearchResultsInGroup : void 0);
|
|
48
36
|
}, [groupByGroupName, searchResults, showGroupedResults, maxSearchResultsInGroup]);
|
|
49
37
|
return {
|
|
50
38
|
searchResults: groupedSearchResults,
|
|
51
|
-
getActiveTabGroup
|
|
52
|
-
getGroupName
|
|
39
|
+
getActiveTabGroup,
|
|
40
|
+
getGroupName
|
|
53
41
|
};
|
|
54
|
-
};
|
|
42
|
+
};
|
|
43
|
+
export {
|
|
44
|
+
useSearchResults
|
|
45
|
+
};
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { useRef } from
|
|
2
|
-
import { v4
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* Returns a stable UUID that persists for the lifetime
|
|
6
|
-
* of the component instance.
|
|
7
|
-
*/
|
|
8
|
-
export var useStableId = function useStableId() {
|
|
9
|
-
var idRef = useRef();
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
const useStableId = () => {
|
|
4
|
+
const idRef = useRef();
|
|
10
5
|
if (!idRef.current) {
|
|
11
|
-
idRef.current =
|
|
6
|
+
idRef.current = v4();
|
|
12
7
|
}
|
|
13
8
|
return idRef.current;
|
|
14
|
-
};
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
useStableId
|
|
12
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
interface UseStickyScrollOptions {
|
|
3
|
+
scrollContainerRef: RefObject<HTMLElement>;
|
|
4
|
+
offsetTop?: number;
|
|
5
|
+
offsetBottom?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const useStickyScroll: ({ scrollContainerRef, offsetTop, offsetBottom, }: UseStickyScrollOptions) => RefObject<HTMLDivElement>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
const useStickyScroll = ({
|
|
3
|
+
scrollContainerRef,
|
|
4
|
+
offsetTop = 0,
|
|
5
|
+
offsetBottom = 0
|
|
6
|
+
}) => {
|
|
7
|
+
const stickyRef = useRef(null);
|
|
8
|
+
const lastScrollTop = useRef(0);
|
|
9
|
+
const topValue = useRef(0);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const container = scrollContainerRef.current;
|
|
12
|
+
const sticky = stickyRef.current;
|
|
13
|
+
if (!container || !sticky) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const containerStyle = getComputedStyle(container);
|
|
17
|
+
const paddingTop = parseFloat(containerStyle.paddingTop);
|
|
18
|
+
const paddingBottom = parseFloat(containerStyle.paddingBottom);
|
|
19
|
+
const stickyOriginTop = sticky.offsetTop - paddingTop;
|
|
20
|
+
sticky.style.position = "sticky";
|
|
21
|
+
sticky.style.top = `${offsetTop}px`;
|
|
22
|
+
topValue.current = offsetTop;
|
|
23
|
+
lastScrollTop.current = container.scrollTop;
|
|
24
|
+
const onScroll = () => {
|
|
25
|
+
const scrollTop = container.scrollTop;
|
|
26
|
+
const delta = scrollTop - lastScrollTop.current;
|
|
27
|
+
if (delta === 0) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const engaged = scrollTop >= stickyOriginTop - offsetTop;
|
|
31
|
+
if (!engaged) {
|
|
32
|
+
topValue.current = offsetTop;
|
|
33
|
+
sticky.style.top = `${topValue.current}px`;
|
|
34
|
+
lastScrollTop.current = scrollTop;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const visibleHeight = container.clientHeight - paddingTop - paddingBottom;
|
|
38
|
+
const stickyHeight = sticky.offsetHeight;
|
|
39
|
+
if (stickyHeight <= visibleHeight - offsetTop - offsetBottom) {
|
|
40
|
+
topValue.current = offsetTop;
|
|
41
|
+
} else if (delta > 0) {
|
|
42
|
+
const minTop = visibleHeight - stickyHeight - offsetBottom;
|
|
43
|
+
topValue.current = Math.max(topValue.current - delta, minTop);
|
|
44
|
+
} else {
|
|
45
|
+
topValue.current = Math.min(topValue.current - delta, offsetTop);
|
|
46
|
+
}
|
|
47
|
+
sticky.style.top = `${topValue.current}px`;
|
|
48
|
+
lastScrollTop.current = scrollTop;
|
|
49
|
+
};
|
|
50
|
+
container.addEventListener("scroll", onScroll, {
|
|
51
|
+
passive: true
|
|
52
|
+
});
|
|
53
|
+
return () => container.removeEventListener("scroll", onScroll);
|
|
54
|
+
}, [scrollContainerRef, offsetTop, offsetBottom]);
|
|
55
|
+
return stickyRef;
|
|
56
|
+
};
|
|
57
|
+
export {
|
|
58
|
+
useStickyScroll
|
|
59
|
+
};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
useEffect(
|
|
5
|
-
|
|
6
|
-
var k = _ref[0],
|
|
7
|
-
v = _ref[1];
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
const useTraceUpdate = (props) => {
|
|
3
|
+
const prev = useRef(props);
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const changedProps = Object.entries(props).reduce((ps, [k, v]) => {
|
|
8
6
|
if (prev.current[k] !== v) {
|
|
9
7
|
ps[k] = [prev.current[k], v];
|
|
10
8
|
}
|
|
11
9
|
return ps;
|
|
12
10
|
}, {});
|
|
13
11
|
if (Object.keys(changedProps).length > 0) {
|
|
14
|
-
|
|
15
|
-
console.log('Changed props:', changedProps);
|
|
12
|
+
console.log("Changed props:", changedProps);
|
|
16
13
|
}
|
|
17
14
|
prev.current = props;
|
|
18
15
|
});
|
|
19
|
-
};
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
useTraceUpdate
|
|
19
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Utils UI Component for the Synerise Design System",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": "synerise/synerise-design",
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "
|
|
19
|
+
"build": "vite build",
|
|
20
20
|
"build:css": "node ../../../scripts/style/less.js",
|
|
21
21
|
"build:js": "babel --delete-dir-on-start --root-mode upward src --out-dir dist --extensions '.js,.ts,.tsx'",
|
|
22
|
-
"build:watch": "
|
|
22
|
+
"build:watch": "vite build --watch",
|
|
23
23
|
"defs": "tsc --declaration --outDir dist/ --emitDeclarationOnly",
|
|
24
24
|
"pack:ci": "pnpm pack --pack-destination ../../storybook/storybook-static/static",
|
|
25
25
|
"prepublish": "pnpm run build",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"react": ">=16.9.0 <= 18.3.1",
|
|
43
43
|
"styled-components": "^5.3.3"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "e4ecca8944fc9b41c1b9d59c8bcad5e5e2013225"
|
|
46
46
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|