@addev-be/ui 0.3.3 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@addev-be/ui",
3
- "version": "0.3.3",
3
+ "version": "0.3.6",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "watch": "tsc -b --watch",
@@ -41,6 +41,7 @@
41
41
  "vite-plugin-svgr": "^4.2.0"
42
42
  },
43
43
  "dependencies": {
44
+ "@uidotdev/usehooks": "^2.4.1",
44
45
  "fp-ts": "^2.16.9",
45
46
  "io-ts": "^2.2.21",
46
47
  "lodash": "^4.17.21",
@@ -0,0 +1,69 @@
1
+ import * as styles from './styles';
2
+
3
+ import { DataGridCell } from './DataGridCell';
4
+ import { DataGridRowTemplateProps } from './types';
5
+ import { useContext } from 'react';
6
+
7
+ export const DataGridRowTemplate = <R,>({
8
+ row,
9
+ rowIndex,
10
+ context,
11
+ }: DataGridRowTemplateProps<R>) => {
12
+ const { visibleColumns, rowKeyGetter, toggleSelection, ...props } =
13
+ useContext(context);
14
+
15
+ if (!row) {
16
+ return (
17
+ <styles.DataGridRow key={`loading-row-${rowIndex}`}>
18
+ {!!props.selectable && (
19
+ <styles.LoadingCell className="animate-pulse">
20
+ <div />
21
+ </styles.LoadingCell>
22
+ )}
23
+ {visibleColumns.map((_, index) => (
24
+ <styles.LoadingCell
25
+ className="animate-pulse"
26
+ key={`loading-${rowIndex}-${index}`}
27
+ >
28
+ <div />
29
+ </styles.LoadingCell>
30
+ ))}
31
+ </styles.DataGridRow>
32
+ );
33
+ }
34
+ const key = rowKeyGetter(row);
35
+ const selected = props.selectedKeys.includes(key);
36
+ const { className, style } = props.rowClassNameGetter?.(row) ?? {
37
+ className: '',
38
+ style: undefined,
39
+ };
40
+ return (
41
+ <styles.DataGridRow key={key}>
42
+ {!!props.selectable && (
43
+ <styles.SelectionCell
44
+ key="__select_checkbox__"
45
+ onClick={() => toggleSelection(key)}
46
+ >
47
+ <input
48
+ type="checkbox"
49
+ value={key as string}
50
+ checked={selected}
51
+ readOnly
52
+ />
53
+ </styles.SelectionCell>
54
+ )}
55
+ {visibleColumns.map(([key, col], index) => (
56
+ <DataGridCell
57
+ key={`loading-${rowIndex}-${index}`}
58
+ {...(index === 0 ? { className, style } : {})}
59
+ row={row}
60
+ rowIndex={rowIndex}
61
+ column={col}
62
+ columnIndex={index}
63
+ context={context}
64
+ columnKey={key}
65
+ />
66
+ ))}
67
+ </styles.DataGridRow>
68
+ );
69
+ };
@@ -1,12 +1,11 @@
1
1
  import * as styles from './styles';
2
2
 
3
- import { ReactNode, useContext } from 'react';
4
-
5
- import { DataGridContext } from './types';
3
+ import { DataGridContext, DataGridRowTemplateProps } from './types';
4
+ import { FC, useContext } from 'react';
6
5
 
7
6
  type VirtualScrollerProps<R> = {
8
7
  showAllRows?: boolean;
9
- rowTemplate: (row: R, index: number) => ReactNode;
8
+ rowTemplate: FC<DataGridRowTemplateProps<R>>;
10
9
  hasFooter?: boolean;
11
10
  context: DataGridContext<R>;
12
11
  onRangeChange?: (startIndex: number, length: number) => void;
@@ -22,7 +21,7 @@ export const VirtualScroller = <R,>(props: VirtualScrollerProps<R>) => {
22
21
  gridTemplateColumns,
23
22
  } = useContext(props.context);
24
23
  const {
25
- rowTemplate,
24
+ rowTemplate: RowTemplate,
26
25
  // hasFooter, onRangeChange
27
26
  } = props;
28
27
 
@@ -39,7 +38,9 @@ export const VirtualScroller = <R,>(props: VirtualScrollerProps<R>) => {
39
38
  $topPadding={topPadding}
40
39
  $rowHeight={rowHeight}
41
40
  >
42
- {visibleRows.map(rowTemplate)}
41
+ {visibleRows.map((row, index) => (
42
+ <RowTemplate row={row} rowIndex={index} context={props.context} />
43
+ ))}
43
44
  </styles.VirtualScrollerRowsContainer>
44
45
  </styles.VirtualScrollerContainer>
45
46
  );
@@ -92,6 +92,17 @@ export const useDataGrid = <R,>(
92
92
  onSelectionChange?.(selectedKeys);
93
93
  }, [onSelectionChange, selectedKeys]);
94
94
 
95
+ const toggleSelection = useCallback(
96
+ (key: string) => {
97
+ if (selectedKeys.includes(key)) {
98
+ setSelectedKeys(selectedKeys.filter((p) => p !== key));
99
+ } else {
100
+ setSelectedKeys([...selectedKeys, key]);
101
+ }
102
+ },
103
+ [selectedKeys, setSelectedKeys]
104
+ );
105
+
95
106
  /** ROWS FILTERING **/
96
107
 
97
108
  const [filters, setFilters] = useState<DataGridFilters>({});
@@ -240,6 +251,7 @@ export const useDataGrid = <R,>(
240
251
  footers,
241
252
  setFooters,
242
253
  footerFunctions,
254
+ toggleSelection,
243
255
  ...override,
244
256
  }),
245
257
  [
@@ -265,6 +277,7 @@ export const useDataGrid = <R,>(
265
277
  gridTemplateColumns,
266
278
  footers,
267
279
  footerFunctions,
280
+ toggleSelection,
268
281
  override,
269
282
  ]
270
283
  );
@@ -298,6 +311,7 @@ export const useDataGrid = <R,>(
298
311
  gridTemplateColumns: '',
299
312
  footers: {},
300
313
  setFooters: () => {},
314
+ toggleSelection: () => {},
301
315
  }),
302
316
  []
303
317
  );
@@ -2,11 +2,10 @@ import * as styles from './styles';
2
2
 
3
3
  import { DataGridContextProps, DataGridProps } from './types';
4
4
 
5
- import { DataGridCell } from './DataGridCell';
6
5
  import { DataGridFooter } from './DataGridFooter';
7
6
  import { DataGridHeader } from './DataGridHeader';
7
+ import { DataGridRowTemplate } from './DataGridRowTemplate';
8
8
  import { VirtualScroller } from './VirtualScroller';
9
- import { useCallback } from 'react';
10
9
  import { useDataGrid } from './hooks';
11
10
 
12
11
  /* eslint-disable @typescript-eslint/no-explicit-any */
@@ -25,95 +24,16 @@ export const DataGrid = <R,>({
25
24
  } = props;
26
25
  const [contextProps, DataGridContext] = useDataGrid(props, contextOverride);
27
26
  const {
28
- selectedKeys,
29
- setSelectedKeys,
30
27
  columns,
31
- visibleColumns,
32
28
  rowHeight = 32,
33
29
  headerRowHeight = 40,
34
30
  scrollableRef,
35
31
  onScroll,
36
- rowKeyGetter,
37
32
  } = contextProps;
38
33
 
39
34
  const hasFooter = Object.values(columns).some((col) => col.footer);
40
35
 
41
- const toggleSelection = useCallback(
42
- (key: string) => {
43
- if (selectedKeys.includes(key)) {
44
- setSelectedKeys(selectedKeys.filter((p) => p !== key));
45
- } else {
46
- setSelectedKeys([...selectedKeys, key]);
47
- }
48
- },
49
- [selectedKeys, setSelectedKeys]
50
- );
51
-
52
- const rowTemplate = useCallback(
53
- (row: R, rowIndex: number) => {
54
- if (!row) {
55
- return (
56
- <styles.DataGridRow key={`loading-row-${rowIndex}`}>
57
- {!!props.selectable && (
58
- <styles.LoadingCell className="animate-pulse">
59
- <div />
60
- </styles.LoadingCell>
61
- )}
62
- {visibleColumns.map((_, index) => (
63
- <styles.LoadingCell
64
- className="animate-pulse"
65
- key={`loading-${rowIndex}-${index}`}
66
- >
67
- <div />
68
- </styles.LoadingCell>
69
- ))}
70
- </styles.DataGridRow>
71
- );
72
- }
73
- const key = rowKeyGetter(row);
74
- const { className, style } = props.rowClassNameGetter?.(row) ?? {
75
- className: '',
76
- style: undefined,
77
- };
78
- return (
79
- <styles.DataGridRow key={key}>
80
- {!!props.selectable && (
81
- <styles.SelectionCell
82
- key="__select_checkbox__"
83
- onClick={() => toggleSelection(key)}
84
- >
85
- <input
86
- type="checkbox"
87
- value={key as string}
88
- checked={selectedKeys.includes(key)}
89
- readOnly
90
- />
91
- </styles.SelectionCell>
92
- )}
93
- {visibleColumns.map(([key, col], index) => (
94
- <DataGridCell
95
- key={`loading-${rowIndex}-${index}`}
96
- {...(index === 0 ? { className, style } : {})}
97
- row={row}
98
- rowIndex={rowIndex}
99
- column={col}
100
- columnIndex={index}
101
- context={DataGridContext}
102
- columnKey={key}
103
- />
104
- ))}
105
- </styles.DataGridRow>
106
- );
107
- },
108
- [
109
- DataGridContext,
110
- props,
111
- rowKeyGetter,
112
- selectedKeys,
113
- toggleSelection,
114
- visibleColumns,
115
- ]
116
- );
36
+ const rowTemplate = DataGridRowTemplate;
117
37
 
118
38
  return (
119
39
  <DataGridContext.Provider value={contextProps}>
@@ -131,6 +131,7 @@ export type DataGridContextProps<R> = DataGridProps<R> & {
131
131
  length: number;
132
132
  rowKeyGetter: (row: R) => string;
133
133
  gridTemplateColumns: string;
134
+ toggleSelection: (key: string) => void;
134
135
  };
135
136
 
136
137
  export type DataGridContext<R> = Context<DataGridContextProps<R>>;
@@ -265,3 +266,11 @@ export type DataGridFilterCheckbox = {
265
266
  values: DataGridFilterValue[];
266
267
  level: number;
267
268
  };
269
+
270
+ export type DataGridRowTemplateProps<R> = {
271
+ row: R | null;
272
+ rowIndex: number;
273
+ selected?: boolean;
274
+ toggleSelection?: () => void;
275
+ context: DataGridContext<R>;
276
+ };
@@ -15,6 +15,8 @@ export const inputStyle = css`
15
15
  }
16
16
  `;
17
17
 
18
- export const Input = styled.input`
18
+ export const Input = styled.input.attrs({
19
+ className: 'Input',
20
+ })`
19
21
  ${inputStyle}
20
22
  `;
@@ -1,3 +1,4 @@
1
1
  export * from './data';
2
2
  export * from './forms';
3
3
  export * from './layout';
4
+ export * from './search';
@@ -57,6 +57,7 @@ const getDropdownStyle = (dropdown: DropdownProps): CSSProperties => {
57
57
  export const Dropdown: FC<DropdownProps> = ({
58
58
  children,
59
59
  onClose,
60
+ $backdropAlpha,
60
61
  ...props
61
62
  }) => {
62
63
  const { createPortal } = usePortals();
@@ -66,13 +67,13 @@ export const Dropdown: FC<DropdownProps> = ({
66
67
  const modalPortal = useMemo(
67
68
  () =>
68
69
  createPortal(
69
- <styles.DropdownBackdrop onClick={onClose}>
70
+ <styles.DropdownBackdrop onClick={onClose} $alpha={$backdropAlpha}>
70
71
  <styles.DropdownContainer {...props} style={style}>
71
72
  {children}
72
73
  </styles.DropdownContainer>
73
74
  </styles.DropdownBackdrop>
74
75
  ),
75
- [children, createPortal, onClose, props, style]
76
+ [$backdropAlpha, children, createPortal, onClose, props, style]
76
77
  );
77
78
 
78
79
  return <>{modalPortal}</>;
@@ -1,6 +1,6 @@
1
1
  import styled, { css } from 'styled-components';
2
2
 
3
- export const DropdownBackdrop = styled.div.attrs({
3
+ export const DropdownBackdrop = styled.div.attrs<{ $alpha?: number }>({
4
4
  className: 'DropdownBackdrop',
5
5
  })`
6
6
  position: absolute;
@@ -9,7 +9,7 @@ export const DropdownBackdrop = styled.div.attrs({
9
9
  left: 0;
10
10
  right: 0;
11
11
  bottom: 0;
12
- background-color: rgba(0, 0, 0, 0.5);
12
+ background: rgba(0, 0, 0, ${({ $alpha = 0.5 }) => $alpha});
13
13
  display: flex;
14
14
  justify-content: center;
15
15
  align-items: center;
@@ -19,6 +19,7 @@ export type DropdownContainerProps = {
19
19
  $width: number;
20
20
  $height: number | number[];
21
21
  $zIndex?: number;
22
+ $backdropAlpha?: number;
22
23
  };
23
24
 
24
25
  export const DropdownContainer = styled.div.attrs({
@@ -0,0 +1,30 @@
1
+ import { FC, HTMLAttributes } from 'react';
2
+
3
+ export const HighlightedText: FC<
4
+ {
5
+ text: string;
6
+ highlight?: string;
7
+ style?: React.CSSProperties;
8
+ } & HTMLAttributes<HTMLSpanElement>
9
+ > = ({ text, highlight, ...props }) => {
10
+ const parts = text?.split(new RegExp(`(${highlight})`, 'gi')) ?? [];
11
+ if (!highlight) return <span {...props}>{text}</span>;
12
+ return (
13
+ <span {...props}>
14
+ {parts
15
+ .filter((part) => !!part)
16
+ .map((part, index) => (
17
+ <span
18
+ key={index}
19
+ style={
20
+ part.toLowerCase() === highlight.toLowerCase()
21
+ ? { backgroundColor: 'gold' }
22
+ : {}
23
+ }
24
+ >
25
+ {part}
26
+ </span>
27
+ ))}
28
+ </span>
29
+ );
30
+ };
@@ -0,0 +1,80 @@
1
+ import * as styles from './styles';
2
+
3
+ import { SearchResults, SearchTypeDefinitions } from './types';
4
+ import { useCallback, useEffect, useRef, useState } from 'react';
5
+
6
+ import { Dropdown } from '../layout';
7
+ import { Input } from '../forms';
8
+ import { QuickSearchResults } from './QuickSearchResults';
9
+ import { useDebounce } from '@uidotdev/usehooks';
10
+ import { useGlobalSearchRequestHandler } from '../../services';
11
+
12
+ type QuickSearchBarProps<R> = {
13
+ definitions: SearchTypeDefinitions<R>;
14
+ };
15
+
16
+ export const QuickSearchBar = <R,>({ definitions }: QuickSearchBarProps<R>) => {
17
+ const [term, setTerm] = useState('');
18
+ const [dropdownVisible, setDropdownVisible] = useState(false);
19
+ const debouncedTerm = useDebounce(term, 300);
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ const [results, setResults] = useState<SearchResults<R> | null>(null);
22
+
23
+ const fakeInputRef = useRef<HTMLInputElement | null>(null);
24
+ const inputRef = useRef<HTMLInputElement | null>(null);
25
+ const rect = fakeInputRef.current?.getBoundingClientRect() ?? new DOMRect();
26
+ const destRect = new DOMRect(rect.x, rect.y, rect.width, 0);
27
+ const globalSearch = useGlobalSearchRequestHandler();
28
+
29
+ useEffect(() => {
30
+ if (debouncedTerm) {
31
+ globalSearch({
32
+ types: ['Customer', 'ScanGroup'],
33
+ searchTerm: debouncedTerm,
34
+ limit: 5,
35
+ }).then((response) => {
36
+ setResults(response.data as SearchResults<R>);
37
+ setDropdownVisible(true);
38
+ });
39
+ }
40
+ }, [globalSearch, debouncedTerm]);
41
+
42
+ const onFocus = useCallback(() => {
43
+ setDropdownVisible(true);
44
+ requestAnimationFrame(() => {
45
+ inputRef.current?.focus();
46
+ });
47
+ }, []);
48
+
49
+ return (
50
+ <>
51
+ <Input type="text" ref={fakeInputRef} value={term} onFocus={onFocus} />
52
+ {dropdownVisible && rect && (
53
+ <Dropdown
54
+ $sourceRect={destRect}
55
+ onClose={() => setDropdownVisible(false)}
56
+ $width={rect.width}
57
+ $height={[results ? 250 : rect.height, 400]}
58
+ $autoPositionY={false}
59
+ >
60
+ <styles.QuickSearchDropdownContainer>
61
+ <Input
62
+ type="text"
63
+ ref={inputRef}
64
+ value={term}
65
+ onChange={(e) => setTerm(e.target.value)}
66
+ onClick={(e) => e.stopPropagation()}
67
+ />
68
+ {results && (
69
+ <QuickSearchResults
70
+ results={results}
71
+ definitions={definitions}
72
+ term={debouncedTerm}
73
+ />
74
+ )}
75
+ </styles.QuickSearchDropdownContainer>
76
+ </Dropdown>
77
+ )}
78
+ </>
79
+ );
80
+ };
@@ -0,0 +1,86 @@
1
+ import * as styles from './styles';
2
+
3
+ import { ReactNode, useMemo, useState } from 'react';
4
+ import { ResultArray, SearchResults, SearchTypeDefinitions } from './types';
5
+
6
+ import { pickBy } from 'lodash';
7
+
8
+ type QuickSearchResultsProps<R> = {
9
+ definitions: SearchTypeDefinitions<R>;
10
+ results: SearchResults<R>;
11
+ term: string;
12
+ };
13
+
14
+ export const QuickSearchResults = <R,>(props: QuickSearchResultsProps<R>) => {
15
+ const { definitions, results: allResults, term } = props;
16
+ const [highlightedIndex, setHighlightedIndex] = useState(-1);
17
+
18
+ const notEmptyResults = pickBy<R[keyof R][]>(
19
+ allResults,
20
+ (results) => results.length > 0
21
+ );
22
+ const resultsArray = useMemo(
23
+ () =>
24
+ Object.keys(notEmptyResults).reduce(
25
+ (acc, type) => [
26
+ ...acc,
27
+ ...notEmptyResults[type].map((result) => ({
28
+ result,
29
+ type: type as keyof R,
30
+ })),
31
+ ],
32
+ [] as ResultArray<R>
33
+ ),
34
+ [notEmptyResults]
35
+ );
36
+
37
+ const elements = useMemo(() => {
38
+ const elements: ReactNode[] = [];
39
+ let currentType: keyof R | null = null;
40
+ resultsArray.forEach(({ result, type }, index) => {
41
+ const definition = definitions[type];
42
+ if (currentType !== type) {
43
+ currentType = type;
44
+ elements.push(
45
+ <styles.QuickSearchResultsTitle key={`title-${String(type)}`}>
46
+ {definition.title}
47
+ </styles.QuickSearchResultsTitle>
48
+ );
49
+ }
50
+ elements.push(
51
+ <styles.QuickSearchResultsItem
52
+ key={`result-${index}`}
53
+ onClick={() => definition.onClick?.(result)}
54
+ onMouseEnter={() => setHighlightedIndex(index)}
55
+ className={highlightedIndex === index ? 'highlighted' : ''}
56
+ >
57
+ {definition.quickRenderer(result, term)}
58
+ </styles.QuickSearchResultsItem>
59
+ );
60
+ });
61
+ return elements;
62
+ }, [definitions, highlightedIndex, resultsArray, term]);
63
+
64
+ const highlightedResult = resultsArray[highlightedIndex];
65
+ const highlightedDefinition = highlightedResult
66
+ ? definitions[highlightedResult?.type]
67
+ : null;
68
+
69
+ return (
70
+ <styles.QuickSearchResultsContainer>
71
+ <styles.QuickSearchResultsListContainer>
72
+ {elements}
73
+ </styles.QuickSearchResultsListContainer>
74
+ {highlightedDefinition && (
75
+ <styles.QuickSearchResultsDetailsContainer>
76
+ {highlightedDefinition.titleRenderer(highlightedResult.result, term)}
77
+ <styles.QuickSearchResultsDetailsDivider />
78
+ {highlightedDefinition.detailsRenderer(
79
+ highlightedResult.result,
80
+ term
81
+ )}
82
+ </styles.QuickSearchResultsDetailsContainer>
83
+ )}
84
+ </styles.QuickSearchResultsContainer>
85
+ );
86
+ };
@@ -0,0 +1,5 @@
1
+ export * from './QuickSearchBar';
2
+ export * from './QuickSearchResults';
3
+ export * from './HighlightedText';
4
+ export * from './types';
5
+ export { QuickSearchResultDetailsTitle } from './styles';
@@ -0,0 +1,79 @@
1
+ import styled from 'styled-components';
2
+
3
+ export const QuickSearchDropdownContainer = styled.div.attrs({
4
+ className: 'QuickSearchDropdownContainer',
5
+ })`
6
+ display: flex;
7
+ flex-direction: column;
8
+ height: 100%;
9
+ `;
10
+
11
+ export const QuickSearchResultsContainer = styled.div.attrs({
12
+ className: 'QuickSearchResultsContainer',
13
+ })`
14
+ display: flex;
15
+ flex-direction: row;
16
+ height: 100%;
17
+ flex: 1;
18
+ padding: var(--space-2) 0;
19
+ overflow: hidden;
20
+ `;
21
+
22
+ export const QuickSearchResultsListContainer = styled.div.attrs({
23
+ className: 'QuickSearchResultsListContainer',
24
+ })`
25
+ display: flex;
26
+ flex-direction: column;
27
+ padding: var(--space-2);
28
+ border-right: 1px solid var(--color-neutral-200);
29
+ flex: 1;
30
+ overflow: auto;
31
+ `;
32
+
33
+ export const QuickSearchResultsTitle = styled.div.attrs({
34
+ className: 'QuickSearchResultsTitle',
35
+ })`
36
+ margin: 0;
37
+ margin-bottom: var(--space-1);
38
+ &:not(:first-child) {
39
+ margin-top: var(--space-2);
40
+ }
41
+ font-weight: bold;
42
+ font-size: var(--text-sm);
43
+ text-transform: uppercase;
44
+ letter-spacing: 120%;
45
+ color: var(--color-neutral-500);
46
+ `;
47
+
48
+ export const QuickSearchResultsItem = styled.div.attrs({
49
+ className: 'QuickSearchResultsItem',
50
+ })`
51
+ padding: var(--space-2) var(--space-3);
52
+ cursor: pointer;
53
+ border-radius: 4px;
54
+ &:hover {
55
+ background-color: var(--color-neutral-100);
56
+ }
57
+ `;
58
+
59
+ export const QuickSearchResultsDetailsContainer = styled.div.attrs({
60
+ className: 'QuickSearchResultsDetailsContainer',
61
+ })`
62
+ display: flex;
63
+ flex-direction: column;
64
+ padding: var(--space-2);
65
+ flex: 1;
66
+ `;
67
+
68
+ export const QuickSearchResultsDetailsDivider = styled.hr`
69
+ margin: var(--space-2) 0;
70
+ height: 1px;
71
+ border: none;
72
+ background-color: var(--color-neutral-200);
73
+ `;
74
+
75
+ export const QuickSearchResultDetailsTitle = styled.div.attrs({
76
+ className: 'QuickSearchResultDetailsTitle',
77
+ })`
78
+ margin: 0;
79
+ `;
@@ -0,0 +1,26 @@
1
+ import { FC, ReactNode } from 'react';
2
+
3
+ export type SearchTypeDefinition<T> = {
4
+ title: string;
5
+ quickRenderer: (result: T, term: string) => ReactNode;
6
+ titleRenderer: (result: T, term: string) => ReactNode;
7
+ detailsRenderer: (result: T, term: string) => ReactNode;
8
+ onClick?: (result: T) => void;
9
+ };
10
+
11
+ export type SearchTypeDefinitions<R> = {
12
+ [K in keyof R]: SearchTypeDefinition<R[K]>;
13
+ };
14
+
15
+ export type SearchResults<R> = {
16
+ [K in keyof R]: Array<R[K]>;
17
+ };
18
+
19
+ export type SearchDetailsFC<T> = FC<{
20
+ searchResult: T;
21
+ }>;
22
+
23
+ export type ResultArray<R> = {
24
+ result: R[keyof R];
25
+ type: keyof R;
26
+ }[];
@@ -0,0 +1,2 @@
1
+ export * from './dates';
2
+ export * from './numbers';
package/src/index.ts CHANGED
@@ -4,4 +4,5 @@ export * from './providers';
4
4
  export * from './Icons';
5
5
 
6
6
  export * from './config';
7
+ export * from './helpers';
7
8
  export * from './services';
@@ -1,4 +1,4 @@
1
1
  export { ThemeProvider } from './ThemeProvider';
2
2
 
3
- export { type Theme } from './types';
3
+ export * from './types';
4
4
  export { defaultTheme } from './defaultTheme';
@@ -45,6 +45,7 @@ export class WebSocketService {
45
45
  if (this.socket && this.socket.readyState === 1) {
46
46
  clearInterval(interval);
47
47
  this.setStatus(true);
48
+ this.sendQueue();
48
49
  this.onOpen?.();
49
50
  }
50
51
  }, 100);
@@ -2,6 +2,7 @@ export * from './WebSocketService';
2
2
  export * from './hooks';
3
3
 
4
4
  export * from './requests/auth';
5
+ export * from './globalSearch';
5
6
 
6
7
  export * from './types/auth';
7
8
  export * from './types/base';