@true-engineering/true-react-common-ui-kit 4.0.0-alpha54 → 4.0.0-alpha61
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 +1 -0
- package/dist/components/AddButton/AddButton.d.ts +1 -0
- package/dist/components/AddButton/AddButton.styles.d.ts +1 -1
- package/dist/components/Button/Button.styles.d.ts +1 -1
- package/dist/components/Checkbox/Checkbox.styles.d.ts +1 -1
- package/dist/components/ControlWrapper/ControlWrapper.d.ts +1 -1
- package/dist/components/ControlWrapper/ControlWrapper.styles.d.ts +1 -1
- package/dist/components/CssBaseline/CssBaseline.styles.d.ts +1 -1
- package/dist/components/DatePicker/components/DatePickerHeader/DatePickerHeader.styles.d.ts +1 -1
- package/dist/components/Description/Description.styles.d.ts +1 -1
- package/dist/components/FileInput/FileInput.styles.d.ts +1 -1
- package/dist/components/FileItem/FileItem.styles.d.ts +1 -1
- package/dist/components/FiltersPane/components/FilterInterval/FilterInterval.styles.d.ts +1 -1
- package/dist/components/FiltersPane/components/FilterSelect/FilterSelect.styles.d.ts +2 -2
- package/dist/components/FiltersPane/components/FilterWithDates/FilterWithDates.styles.d.ts +2 -2
- package/dist/components/FiltersPane/components/FilterWrapper/FilterWrapper.d.ts +1 -1
- package/dist/components/FiltersPane/components/FilterWrapper/FilterWrapper.styles.d.ts +1 -1
- package/dist/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.styles.d.ts +1 -1
- package/dist/components/FiltersPane/types.d.ts +2 -1
- package/dist/components/FlexibleTable/FlexibleTable.styles.d.ts +1 -1
- package/dist/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.styles.d.ts +1 -1
- package/dist/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.d.ts +1 -3
- package/dist/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.styles.d.ts +1 -1
- package/dist/components/FloatDocActions/components/DocActions/DocActions.styles.d.ts +1 -1
- package/dist/components/IconButton/IconButton.styles.d.ts +1 -1
- package/dist/components/List/components/ListItem/ListItem.styles.d.ts +1 -1
- package/dist/components/Modal/Modal.styles.d.ts +1 -1
- package/dist/components/MoreMenu/MoreMenu.styles.d.ts +1 -1
- package/dist/components/MultiSelect/MultiSelect.styles.d.ts +1 -1
- package/dist/components/MultiSelect/components/MultiSelectInput/MultiSelectInput.styles.d.ts +1 -1
- package/dist/components/MultiSelectList/MultiSelectList.styles.d.ts +1 -1
- package/dist/components/NewMoreMenu/NewMoreMenu.styles.d.ts +1 -1
- package/dist/components/Notification/Notification.styles.d.ts +1 -1
- package/dist/components/PhoneInput/PhoneInput.styles.d.ts +1 -1
- package/dist/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.styles.d.ts +1 -1
- package/dist/components/RadioButton/RadioButton.styles.d.ts +1 -1
- package/dist/components/SearchInput/SearchInput.d.ts +1 -1
- package/dist/components/Select/Select.styles.d.ts +3 -3
- package/dist/components/Select/components/SelectList/SelectList.styles.d.ts +1 -1
- package/dist/components/Selector/Selector.styles.d.ts +1 -1
- package/dist/components/Status/Status.styles.d.ts +1 -1
- package/dist/components/Switch/Switch.d.ts +3 -2
- package/dist/components/Switch/Switch.styles.d.ts +3 -2
- package/dist/components/Switch/types.d.ts +3 -0
- package/dist/components/TextArea/TextArea.styles.d.ts +1 -1
- package/dist/components/TextButton/TextButton.styles.d.ts +1 -1
- package/dist/components/TextWithInfo/TextWithInfo.styles.d.ts +1 -1
- package/dist/components/TextWithTooltip/TextWithTooltip.d.ts +2 -0
- package/dist/components/TextWithTooltip/TextWithTooltip.styles.d.ts +1 -1
- package/dist/components/ThemedPreloader/ThemedPreloader.styles.d.ts +1 -1
- package/dist/components/ThemedPreloader/components/DotsPreloader/DotsPreloader.styles.d.ts +1 -1
- package/dist/components/Toaster/Toaster.styles.d.ts +1 -1
- package/dist/components/Tooltip/Tooltip.d.ts +3 -0
- package/dist/components/Tooltip/Tooltip.styles.d.ts +2 -1
- package/dist/components/Tooltip/types.d.ts +3 -0
- package/dist/components/WithMessages/WithMessages.styles.d.ts +1 -1
- package/dist/components/WithPopup/WithPopup.styles.d.ts +1 -1
- package/dist/components/WithTooltip/WithTooltip.d.ts +2 -0
- package/dist/helpers/misc.d.ts +2 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/use-intersection-ref.d.ts +2 -1
- package/dist/hooks/use-resize-ref.d.ts +7 -0
- package/dist/hooks/use-tweak-styles.d.ts +3 -2
- package/dist/theme/Provider.d.ts +2 -12
- package/dist/theme/common.d.ts +34 -4
- package/dist/theme/helpers.d.ts +3 -16
- package/dist/theme/index.d.ts +0 -2
- package/dist/theme/types.d.ts +9 -8
- package/dist/true-react-common-ui-kit.js +12132 -10
- package/dist/true-react-common-ui-kit.js.map +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs +2 -10
- package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
- package/dist/types.d.ts +3 -3
- package/package.json +1 -3
- package/src/components/AccountInfo/AccountInfo.tsx +2 -3
- package/src/components/AddButton/AddButton.tsx +3 -5
- package/src/components/Button/Button.tsx +76 -77
- package/src/components/CloseButton/CloseButton.tsx +2 -4
- package/src/components/Colors/Colors.stories.tsx +3 -2
- package/src/components/ControlWrapper/ControlWrapper.tsx +2 -2
- package/src/components/CssBaseline/CssBaseline.styles.ts +2 -0
- package/src/components/CssBaseline/CssBaseline.tsx +2 -3
- package/src/components/DateInput/DateInput.tsx +59 -61
- package/src/components/DatePicker/DatePicker.tsx +259 -262
- package/src/components/Description/Description.tsx +2 -3
- package/src/components/FileInput/FileInput.tsx +87 -95
- package/src/components/FileItem/FileItem.tsx +2 -4
- package/src/components/FiltersPane/FiltersPane.stories.tsx +3 -0
- package/src/components/FiltersPane/components/FilterInterval/FilterInterval.tsx +2 -3
- package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.tsx +6 -3
- package/src/components/FiltersPane/components/FilterWrapper/FilterWrapper.tsx +3 -2
- package/src/components/FiltersPane/types.ts +2 -0
- package/src/components/FlexibleTable/FlexibleTable.styles.ts +1 -0
- package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.styles.ts +1 -0
- package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.tsx +5 -2
- package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.tsx +9 -7
- package/src/components/IconButton/IconButton.tsx +44 -48
- package/src/components/Input/Input.tsx +26 -24
- package/src/components/Input/InputBase.tsx +183 -187
- package/src/components/List/List.tsx +2 -3
- package/src/components/List/components/ListItem/ListItem.tsx +2 -4
- package/src/components/Modal/Modal.tsx +2 -4
- package/src/components/MoreMenu/MoreMenu.tsx +2 -4
- package/src/components/MultiSelect/MultiSelect.tsx +2 -4
- package/src/components/NewMoreMenu/NewMoreMenu.tsx +2 -4
- package/src/components/Notification/Notification.tsx +2 -3
- package/src/components/NumberInput/NumberInput.tsx +91 -93
- package/src/components/PhoneInput/PhoneInput.tsx +2 -3
- package/src/components/SearchInput/SearchInput.tsx +20 -19
- package/src/components/Select/Select.tsx +1 -1
- package/src/components/Selector/Selector.tsx +4 -6
- package/src/components/SmartInput/SmartInput.tsx +85 -87
- package/src/components/Status/Status.tsx +5 -4
- package/src/components/Switch/Switch.styles.ts +21 -13
- package/src/components/Switch/Switch.tsx +11 -6
- package/src/components/Switch/types.ts +5 -0
- package/src/components/TextArea/TextArea.tsx +128 -130
- package/src/components/TextButton/TextButton.tsx +68 -69
- package/src/components/TextWithInfo/TextWithInfo.tsx +2 -4
- package/src/components/TextWithTooltip/TextWithTooltip.tsx +6 -4
- package/src/components/ThemedPreloader/ThemedPreloader.tsx +2 -4
- package/src/components/Toaster/Toaster.tsx +2 -4
- package/src/components/Tooltip/Tooltip.stories.tsx +10 -0
- package/src/components/Tooltip/Tooltip.styles.ts +2 -1
- package/src/components/Tooltip/Tooltip.tsx +12 -5
- package/src/components/Tooltip/types.ts +5 -0
- package/src/components/WithMessages/WithMessages.tsx +41 -40
- package/src/components/WithTooltip/WithTooltip.tsx +4 -0
- package/src/helpers/misc.ts +6 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-intersection-ref.ts +24 -6
- package/src/hooks/use-latest-ref.ts +6 -2
- package/src/hooks/use-resize-ref.ts +35 -0
- package/src/hooks/use-tweak-styles.ts +14 -51
- package/src/theme/Provider.tsx +4 -21
- package/src/theme/common.ts +33 -36
- package/src/theme/helpers.ts +50 -42
- package/src/theme/index.ts +0 -2
- package/src/theme/types.ts +13 -10
- package/src/types.ts +3 -3
- package/dist/theme/create-themed-styles.d.ts +0 -2
- package/dist/theme/true-jss/ThemedStylesManager.d.ts +0 -18
- package/dist/theme/true-jss/TweakStylesManager.d.ts +0 -34
- package/dist/theme/true-jss/index.d.ts +0 -2
- package/dist/theme/true-jss/jss-context.d.ts +0 -9
- package/dist/true-react-common-ui-kit.css +0 -756
- package/src/theme/create-themed-styles.ts +0 -78
- package/src/theme/true-jss/ThemedStylesManager.ts +0 -93
- package/src/theme/true-jss/TweakStylesManager.ts +0 -156
- package/src/theme/true-jss/index.ts +0 -2
- package/src/theme/true-jss/jss-context.tsx +0 -34
|
@@ -15,45 +15,46 @@ export interface IWithMessagesProps extends ICommonProps<IWithMessagesStyles> {
|
|
|
15
15
|
controlsDirection?: 'horizontal' | 'vertical';
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export const WithMessages = forwardRef<HTMLDivElement, IWithMessagesProps>(
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
export const WithMessages = forwardRef<HTMLDivElement, IWithMessagesProps>(function WithMessages(
|
|
19
|
+
{ children, infoMessage, errorMessage, controlsDirection, tweakStyles, testId, data },
|
|
20
|
+
ref,
|
|
21
|
+
) {
|
|
22
|
+
const classes = useStyles({ theme: tweakStyles });
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
const shouldShowError = isReactNodeNotEmpty(errorMessage);
|
|
25
|
+
const shouldShowInfo = isReactNodeNotEmpty(infoMessage) && !shouldShowError;
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
);
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
ref={ref}
|
|
30
|
+
className={classes.withMessages}
|
|
31
|
+
data-invalid={shouldShowError ? true : undefined}
|
|
32
|
+
{...addDataAttributes(data, testId)}
|
|
33
|
+
>
|
|
34
|
+
{isReactNodeNotEmpty(children) && (
|
|
35
|
+
<div
|
|
36
|
+
className={clsx(classes.children, {
|
|
37
|
+
[classes.horizontal]: controlsDirection === 'horizontal',
|
|
38
|
+
[classes.vertical]: controlsDirection === 'vertical',
|
|
39
|
+
})}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
</div>
|
|
43
|
+
)}
|
|
44
|
+
{(shouldShowError || shouldShowInfo) && (
|
|
45
|
+
<div className={classes.message}>
|
|
46
|
+
{shouldShowError && (
|
|
47
|
+
<div className={classes.error} {...addDataTestId(testId, 'error')}>
|
|
48
|
+
{errorMessage}
|
|
49
|
+
</div>
|
|
50
|
+
)}
|
|
51
|
+
{shouldShowInfo && (
|
|
52
|
+
<div className={classes.info} {...addDataTestId(testId, 'info')}>
|
|
53
|
+
{infoMessage}
|
|
54
|
+
</div>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
});
|
|
@@ -22,6 +22,8 @@ export interface IWithTooltipProps
|
|
|
22
22
|
tooltipView?: ITooltipProps['view'];
|
|
23
23
|
/** @default 'info' */
|
|
24
24
|
tooltipType?: ITooltipProps['type'];
|
|
25
|
+
/** @default 'undefined' */
|
|
26
|
+
tooltipSize?: ITooltipProps['size'];
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
export const WithTooltip: FC<IWithTooltipProps> = ({
|
|
@@ -31,6 +33,7 @@ export const WithTooltip: FC<IWithTooltipProps> = ({
|
|
|
31
33
|
tooltipText,
|
|
32
34
|
tooltipView = 'tooltip',
|
|
33
35
|
tooltipType = 'info',
|
|
36
|
+
tooltipSize,
|
|
34
37
|
isDisabled = false,
|
|
35
38
|
popupData,
|
|
36
39
|
tweakStyles,
|
|
@@ -64,6 +67,7 @@ export const WithTooltip: FC<IWithTooltipProps> = ({
|
|
|
64
67
|
view={tooltipView}
|
|
65
68
|
type={tooltipType}
|
|
66
69
|
text={tooltipText}
|
|
70
|
+
size={tooltipSize}
|
|
67
71
|
tweakStyles={tweakTooltipStyles}
|
|
68
72
|
testId={getTestId(restProps.testId, 'tooltip')}
|
|
69
73
|
/>
|
package/src/helpers/misc.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ComponentType, memo } from 'react';
|
|
1
2
|
import {
|
|
2
3
|
isNotEmpty,
|
|
3
4
|
isString,
|
|
@@ -160,3 +161,8 @@ export const addDataAttributes = (data: IDataAttributes = {}): IDataAttributes =
|
|
|
160
161
|
|
|
161
162
|
export const excludeStorybookParams = (params: string[]): RegExp =>
|
|
162
163
|
new RegExp(`^(on.*|${['tweakStyles', 'data', ...params].join('|')})$`);
|
|
164
|
+
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
166
|
+
export const genericMemo = memo as <T extends ComponentType<any>>(
|
|
167
|
+
...args: Parameters<typeof memo<T>>
|
|
168
|
+
) => T;
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RefCallback, useMemo } from 'react';
|
|
1
|
+
import { RefCallback, useEffect, useMemo } from 'react';
|
|
2
2
|
import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
|
|
3
3
|
import { useLatestRef } from './use-latest-ref';
|
|
4
4
|
|
|
@@ -7,12 +7,16 @@ export interface IInsertionRefOptions {
|
|
|
7
7
|
isDisabled?: boolean;
|
|
8
8
|
onIntersection?: VoidFunction;
|
|
9
9
|
onIntersectionEnd?: VoidFunction;
|
|
10
|
+
observerOptions?: IntersectionObserverInit;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
export const useIntersectionRef = (
|
|
13
|
+
export const useIntersectionRef = ({
|
|
14
|
+
observerOptions,
|
|
15
|
+
...options
|
|
16
|
+
}: IInsertionRefOptions): RefCallback<Element> => {
|
|
13
17
|
const optionsRef = useLatestRef(options);
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
const { ref, disconnect } = useMemo(() => {
|
|
16
20
|
const observer = new IntersectionObserver(([{ isIntersecting }]) => {
|
|
17
21
|
const { current } = optionsRef;
|
|
18
22
|
if (current?.isDisabled) {
|
|
@@ -23,8 +27,22 @@ export const useIntersectionRef = (options?: IInsertionRefOptions): RefCallback<
|
|
|
23
27
|
} else {
|
|
24
28
|
current?.onIntersectionEnd?.();
|
|
25
29
|
}
|
|
26
|
-
});
|
|
30
|
+
}, observerOptions);
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
const observerRef: RefCallback<Element> = (node) => {
|
|
33
|
+
observer.disconnect();
|
|
34
|
+
if (isNotEmpty(node)) {
|
|
35
|
+
observer.observe(node);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
ref: observerRef,
|
|
41
|
+
disconnect: () => observer.disconnect(),
|
|
42
|
+
};
|
|
43
|
+
}, [optionsRef, observerOptions]);
|
|
44
|
+
|
|
45
|
+
useEffect(() => disconnect, [disconnect]);
|
|
46
|
+
|
|
47
|
+
return ref;
|
|
30
48
|
};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { MutableRefObject, useRef } from 'react';
|
|
1
|
+
import { MutableRefObject, useLayoutEffect, useRef } from 'react';
|
|
2
2
|
|
|
3
3
|
export const useLatestRef = <T>(value: T): MutableRefObject<T> => {
|
|
4
4
|
const ref = useRef(value);
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
useLayoutEffect(() => {
|
|
7
|
+
ref.current = value;
|
|
8
|
+
});
|
|
9
|
+
|
|
6
10
|
return ref;
|
|
7
11
|
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { RefCallback, useMemo, useEffect } from 'react';
|
|
2
|
+
import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
|
|
3
|
+
import { useLatestRef } from './use-latest-ref';
|
|
4
|
+
|
|
5
|
+
export interface IResizeRefOptions {
|
|
6
|
+
/** @default false */
|
|
7
|
+
isDisabled?: boolean;
|
|
8
|
+
onChange: (entry: ResizeObserverEntry) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const useResizeRef = (options: IResizeRefOptions): RefCallback<Element> => {
|
|
12
|
+
const optionsRef = useLatestRef(options);
|
|
13
|
+
|
|
14
|
+
const { ref, disconnect } = useMemo(() => {
|
|
15
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
16
|
+
const { current } = optionsRef;
|
|
17
|
+
if (!current.isDisabled) {
|
|
18
|
+
current?.onChange(entry);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const observerRef: RefCallback<Element> = (node) => {
|
|
23
|
+
observer.disconnect();
|
|
24
|
+
if (isNotEmpty(node)) {
|
|
25
|
+
observer.observe(node);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return { ref: observerRef, disconnect: () => observer.disconnect() };
|
|
30
|
+
}, [optionsRef]);
|
|
31
|
+
|
|
32
|
+
useEffect(() => disconnect, [disconnect]);
|
|
33
|
+
|
|
34
|
+
return ref;
|
|
35
|
+
};
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
isNotEmpty,
|
|
5
|
-
mergeStyles,
|
|
6
|
-
} from '@true-engineering/true-react-platform-helpers';
|
|
7
|
-
import {
|
|
8
|
-
areStylesThemed,
|
|
9
|
-
themedStyles,
|
|
10
|
-
IComponentName,
|
|
11
|
-
IMaybeArray,
|
|
12
|
-
useTheme,
|
|
13
|
-
JssContext,
|
|
14
|
-
IMixedStyles,
|
|
15
|
-
} from '../theme';
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { IMaybeArray } from '@true-engineering/true-react-platform-helpers';
|
|
3
|
+
import { IComponentName, IMixedStyles, useThemeComponentStyles } from '../theme';
|
|
16
4
|
import { mixStyles } from './use-mixed-styles';
|
|
17
5
|
|
|
18
6
|
// TODO: Можно усилить типы
|
|
@@ -37,43 +25,18 @@ export const useTweakStyles = <StyleSheet, ClassName extends keyof StyleSheet &
|
|
|
37
25
|
*/
|
|
38
26
|
className: ClassName;
|
|
39
27
|
/**
|
|
40
|
-
* Название компонента который вызывает useTweakStyles
|
|
28
|
+
* Название компонента который вызывает useTweakStyles
|
|
41
29
|
*/
|
|
42
30
|
currentComponentName?: IComponentName;
|
|
43
31
|
}): Array<NonNullable<StyleSheet[ClassName]>> => {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
mixStyles(themeStyles, tweakStyles).map((style) => style[className]),
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
if (isMergeDisabled || resultStyles.length < 2) {
|
|
58
|
-
return resultStyles;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const [maybeInnerStyles, maybeThemeStyles, ...rest] = resultStyles;
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
maybeThemeStyles !== themeStyles?.[className] || // Если нет themeStyles или innerStyles
|
|
65
|
-
isArrayNotEmpty(rest) // Или есть tweakStyles
|
|
66
|
-
) {
|
|
67
|
-
// Мёржим как есть
|
|
68
|
-
return [mergeStyles(maybeInnerStyles, maybeThemeStyles, ...rest)];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Иначе мёржим themeStyles в innerStyles
|
|
72
|
-
if (!areStylesThemed(maybeInnerStyles)) {
|
|
73
|
-
themedStyles(maybeInnerStyles, maybeThemeStyles);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// И возвращаем только innerStyles
|
|
77
|
-
return [maybeInnerStyles];
|
|
78
|
-
}, [innerStyles, className, currentComponentName, tweakStyles, theme, isMergeDisabled]);
|
|
32
|
+
const themeStyles = useThemeComponentStyles<StyleSheet>(currentComponentName);
|
|
33
|
+
|
|
34
|
+
return useMemo(
|
|
35
|
+
() =>
|
|
36
|
+
mixStyles(
|
|
37
|
+
innerStyles,
|
|
38
|
+
mixStyles(themeStyles, tweakStyles).map((style) => style[className]),
|
|
39
|
+
),
|
|
40
|
+
[innerStyles, className, themeStyles, tweakStyles],
|
|
41
|
+
);
|
|
79
42
|
};
|
package/src/theme/Provider.tsx
CHANGED
|
@@ -1,26 +1,9 @@
|
|
|
1
|
-
import { createContext,
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
2
|
import { common } from './common';
|
|
3
3
|
import type { IUiKitTheme } from './types';
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
theme: IUiKitTheme;
|
|
7
|
-
children: ReactNode;
|
|
8
|
-
}
|
|
5
|
+
export const ThemeContext = createContext<IUiKitTheme>(common);
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
export const ThemeProvider = ThemeContext.Provider;
|
|
11
8
|
|
|
12
|
-
export const
|
|
13
|
-
|
|
14
|
-
interface ThemeContextValue {
|
|
15
|
-
theme: IUiKitTheme;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const ThemeContext = createContext<ThemeContextValue>({ theme: common });
|
|
19
|
-
|
|
20
|
-
export const ThemeProvider: FC<IThemedProviderProps> = ({ theme, children }) => {
|
|
21
|
-
globalTheme = theme;
|
|
22
|
-
const value: ThemeContextValue = useMemo(() => ({ theme }), [theme]);
|
|
23
|
-
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const useTheme = (): IUiKitTheme => useContext(ThemeContext).theme;
|
|
9
|
+
export const useTheme = (): IUiKitTheme => useContext(ThemeContext);
|
package/src/theme/common.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Styles } from 'react-jss';
|
|
2
1
|
import { IUiKitHelpers, IUiKitTheme } from './types';
|
|
3
2
|
|
|
4
3
|
export const colors = {
|
|
@@ -49,41 +48,40 @@ export const dimensions = {
|
|
|
49
48
|
} as const;
|
|
50
49
|
|
|
51
50
|
export const helpers = {
|
|
52
|
-
withAngle: (angleSize = 6, position: 'left' | 'right' = 'left', distance = 100)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
'
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
},
|
|
51
|
+
withAngle: (angleSize = 6, position: 'left' | 'right' = 'left', distance = 100) => ({
|
|
52
|
+
display: 'inline-block',
|
|
53
|
+
position: 'relative',
|
|
54
|
+
marginTop: angleSize * 2 - 1,
|
|
55
|
+
boxShadow: '0 8px 20px 0 rgba(0, 0, 0, 0.04)',
|
|
56
|
+
border: ['solid', 1, colors.BORDER_MAIN],
|
|
57
|
+
borderRadius: dimensions.BORDER_RADIUS_EXTRA_SMALL,
|
|
58
|
+
|
|
59
|
+
'&:before': {
|
|
60
|
+
content: '""',
|
|
61
|
+
position: 'absolute',
|
|
62
|
+
top: -angleSize,
|
|
63
|
+
left: position === 'left' && distance,
|
|
64
|
+
right: position === 'right' && distance,
|
|
65
|
+
width: 0,
|
|
66
|
+
height: 0,
|
|
67
|
+
borderLeft: [angleSize, 'solid', 'transparent'],
|
|
68
|
+
borderRight: [angleSize, 'solid', 'transparent'],
|
|
69
|
+
borderBottom: [angleSize, 'solid', colors.BORDER_MAIN],
|
|
70
|
+
},
|
|
73
71
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
72
|
+
'&:after': {
|
|
73
|
+
content: '""',
|
|
74
|
+
position: 'absolute',
|
|
75
|
+
top: -angleSize + 1,
|
|
76
|
+
left: position === 'left' && distance + 1,
|
|
77
|
+
right: position === 'right' && distance + 1,
|
|
78
|
+
width: 0,
|
|
79
|
+
height: 0,
|
|
80
|
+
borderLeft: [angleSize - 1, 'solid', 'transparent'],
|
|
81
|
+
borderRight: [angleSize - 1, 'solid', 'transparent'],
|
|
82
|
+
borderBottom: [angleSize - 1, 'solid', colors.CLASSIC_WHITE],
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
87
85
|
|
|
88
86
|
withScrollBar: {
|
|
89
87
|
boxSizing: 'border-box',
|
|
@@ -135,7 +133,6 @@ const SLIDE_UP_POSITION_END = 0;
|
|
|
135
133
|
|
|
136
134
|
export const animations = {
|
|
137
135
|
defaultTransition: '0.25s ease-in-out',
|
|
138
|
-
// Если понадобится, сюда можно пробросить параметры через useTheme props
|
|
139
136
|
slideUp: {
|
|
140
137
|
'slide-up-enter': {
|
|
141
138
|
opacity: 0,
|
package/src/theme/helpers.ts
CHANGED
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { createUseStyles } from 'react-jss';
|
|
2
3
|
import {
|
|
3
4
|
isArrayNotEmpty,
|
|
4
5
|
isNotEmpty,
|
|
6
|
+
isString,
|
|
5
7
|
mergeStyles,
|
|
6
8
|
} from '@true-engineering/true-react-platform-helpers';
|
|
7
|
-
import {
|
|
9
|
+
import { mixStyles } from '../hooks/use-mixed-styles';
|
|
10
|
+
import { useTheme } from './Provider';
|
|
11
|
+
import { IComponentName, IStyles, IUseStyles } from './types';
|
|
8
12
|
|
|
9
|
-
const
|
|
13
|
+
export const useThemeComponentStyles = <T>(
|
|
14
|
+
componentName?: IComponentName,
|
|
15
|
+
): Partial<T> | undefined => {
|
|
16
|
+
const { components } = useTheme();
|
|
17
|
+
return isNotEmpty(componentName) ? (components?.[componentName] as never) : undefined;
|
|
18
|
+
};
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
const isTweakStyle = (key: string): boolean => key.startsWith('tweak');
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
const areStylesNotEmpty = <T>(tweakStyles?: T): tweakStyles is NonNullable<T> =>
|
|
14
23
|
isNotEmpty(tweakStyles) && !Object.keys(tweakStyles).every(isTweakStyle);
|
|
15
24
|
|
|
16
|
-
|
|
17
|
-
isStylesNotEmpty(tweakStyles) ? tweakStyles : (EMPTY_STYLES as T);
|
|
18
|
-
|
|
19
|
-
export const mergeTweakStyles = <T>(tweakStyles?: IMaybeArray<T>): T | undefined => {
|
|
20
|
-
if (!Array.isArray(tweakStyles)) {
|
|
21
|
-
return tweakStyles;
|
|
22
|
-
}
|
|
23
|
-
const [first, ...rest] = tweakStyles;
|
|
24
|
-
return isArrayNotEmpty(rest) ? mergeStyles(first, ...rest) : first;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export const checkStyles = (componentName: string, styles: Record<string, unknown>): void => {
|
|
25
|
+
const checkStyles = (styles: IStyles<string>, componentName = 'LocalComponent'): void => {
|
|
28
26
|
const invalidClasses = Object.keys(styles).filter(isTweakStyle);
|
|
29
27
|
|
|
30
28
|
if (isArrayNotEmpty(invalidClasses)) {
|
|
@@ -34,23 +32,8 @@ export const checkStyles = (componentName: string, styles: Record<string, unknow
|
|
|
34
32
|
}
|
|
35
33
|
};
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
styles.__themed === true;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Подмешивает стили из темы. Мутирует, добавляя специально поле,
|
|
43
|
-
* по которому можно определить была ли уже произведена мутация ранее,
|
|
44
|
-
* тем самым сохраняя ссылку на объект и позволяя этим кэшировать JSS стили
|
|
45
|
-
*/
|
|
46
|
-
export const themedStyles = <T>(styles: T, themeComponentStyles: T): T => {
|
|
47
|
-
merge(styles, themeComponentStyles); // mutation !!!!
|
|
48
|
-
Object.defineProperty(styles, '__themed', { value: true });
|
|
49
|
-
return styles;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
type TweakStylesCache = (styles: object[], prev?: object[]) => object | undefined;
|
|
53
|
-
export const getTweakStylesCache = (): TweakStylesCache => {
|
|
35
|
+
type TweakStylesCache = (styles: object[], idx?: number) => object | undefined;
|
|
36
|
+
const getTweakStylesCache = (): TweakStylesCache => {
|
|
54
37
|
let mergedStyles: object | undefined;
|
|
55
38
|
const cache = new WeakMap<object, TweakStylesCache>();
|
|
56
39
|
|
|
@@ -59,20 +42,45 @@ export const getTweakStylesCache = (): TweakStylesCache => {
|
|
|
59
42
|
cache.set(next, getTweakStylesCache());
|
|
60
43
|
}
|
|
61
44
|
|
|
62
|
-
// eslint-disable-
|
|
63
|
-
return cache.get(next)!;
|
|
45
|
+
return cache.get(next)!; // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
|
64
46
|
};
|
|
65
47
|
|
|
66
|
-
return (styles,
|
|
67
|
-
const
|
|
48
|
+
return (styles, idx = 0) => {
|
|
49
|
+
const next = styles.at(idx);
|
|
68
50
|
if (isNotEmpty(next)) {
|
|
69
|
-
return getNext(next)(
|
|
51
|
+
return getNext(next)(styles, idx + 1);
|
|
70
52
|
}
|
|
71
53
|
|
|
72
|
-
if (isNotEmpty(mergedStyles)) {
|
|
73
|
-
|
|
54
|
+
if (!isNotEmpty(mergedStyles)) {
|
|
55
|
+
const [first, ...rest] = styles;
|
|
56
|
+
mergedStyles = isArrayNotEmpty(rest) ? mergeStyles(first, ...rest) : first;
|
|
74
57
|
}
|
|
75
58
|
|
|
76
|
-
return
|
|
59
|
+
return mergedStyles;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const tweakStylesCache = getTweakStylesCache();
|
|
64
|
+
const useStyles = createUseStyles<string>((tweakStyles) => tweakStyles as never);
|
|
65
|
+
|
|
66
|
+
export const createThemedStyles: <C extends string>(
|
|
67
|
+
...args: [IStyles<C>] | [IComponentName, IStyles<C>]
|
|
68
|
+
) => IUseStyles<C> = (first, second?) => {
|
|
69
|
+
const componentName = isString(first) ? first : undefined;
|
|
70
|
+
const styles = second! ?? first; // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
|
71
|
+
|
|
72
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
73
|
+
checkStyles(styles, componentName);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return ({ theme, tweakStyles = theme }) => {
|
|
77
|
+
const themeStyles = useThemeComponentStyles<typeof styles>(componentName);
|
|
78
|
+
|
|
79
|
+
const data = useMemo(() => {
|
|
80
|
+
const resultStyles = mixStyles(styles, themeStyles, tweakStyles).filter(areStylesNotEmpty);
|
|
81
|
+
return { theme: tweakStylesCache(resultStyles) };
|
|
82
|
+
}, [themeStyles, tweakStyles]);
|
|
83
|
+
|
|
84
|
+
return useStyles(data);
|
|
77
85
|
};
|
|
78
86
|
};
|
package/src/theme/index.ts
CHANGED
package/src/theme/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Styles } from '
|
|
2
|
-
import {
|
|
1
|
+
import type { Classes, JssStyle, JssValue, Styles } from 'jss';
|
|
2
|
+
import type { IMaybeArray } from '@true-engineering/true-react-platform-helpers';
|
|
3
3
|
import type {
|
|
4
4
|
IAccountInfoStyles,
|
|
5
5
|
IAddButtonStyles,
|
|
@@ -67,19 +67,22 @@ import type {
|
|
|
67
67
|
IWithTooltipStyles,
|
|
68
68
|
} from '../components';
|
|
69
69
|
|
|
70
|
-
export type IStyles<C extends string
|
|
70
|
+
export type IStyles<C extends string> = Styles<C>;
|
|
71
|
+
|
|
72
|
+
export type IStyle = JssStyle;
|
|
71
73
|
|
|
72
|
-
export type IMaybeArray<T> = T[] | T;
|
|
73
74
|
export type IMixedStyles<T> = IMaybeArray<T | boolean | undefined>;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
|
|
76
|
+
export type IUseStyles<C extends string> = (data: {
|
|
77
|
+
theme?: IMaybeArray<Partial<IStyles<C>>>;
|
|
78
|
+
tweakStyles?: IMaybeArray<Partial<IStyles<C>>>;
|
|
79
|
+
}) => Classes<C>;
|
|
77
80
|
|
|
78
81
|
export type ITweakStyles<
|
|
79
82
|
StyleCreator,
|
|
80
83
|
ChildTweakStyles = unknown,
|
|
81
|
-
> = StyleCreator extends IUseStyles<infer C
|
|
82
|
-
? Partial<
|
|
84
|
+
> = StyleCreator extends IUseStyles<infer C>
|
|
85
|
+
? Partial<IStyles<C>> & Partial<ChildTweakStyles>
|
|
83
86
|
: never;
|
|
84
87
|
|
|
85
88
|
export interface IComponentStyles {
|
|
@@ -149,7 +152,7 @@ export interface IComponentStyles {
|
|
|
149
152
|
export type IComponentName = keyof IComponentStyles;
|
|
150
153
|
|
|
151
154
|
export type IUiKitAnimations = Record<string, any>;
|
|
152
|
-
export type IUiKitHelpers = Record<string,
|
|
155
|
+
export type IUiKitHelpers = Record<string, IStyle | (() => IStyle)>;
|
|
153
156
|
|
|
154
157
|
export interface IUiKitTheme {
|
|
155
158
|
components?: Partial<IComponentStyles>;
|
package/src/types.ts
CHANGED
|
@@ -8,8 +8,8 @@ import type {
|
|
|
8
8
|
ReactNode,
|
|
9
9
|
} from 'react';
|
|
10
10
|
import type { Modifier, Placement } from 'react-overlays/usePopper';
|
|
11
|
-
import type {
|
|
12
|
-
import
|
|
11
|
+
import type { IMaybeArray } from '@true-engineering/true-react-platform-helpers';
|
|
12
|
+
import { IStyle } from './theme';
|
|
13
13
|
|
|
14
14
|
export interface ITestIdProps {
|
|
15
15
|
testId?: string;
|
|
@@ -66,7 +66,7 @@ export type IRenderNode<T> = ReactNode | ((props: T) => ReactNode);
|
|
|
66
66
|
|
|
67
67
|
export type IExtendableProps<T extends string | readonly string[]> = Record<
|
|
68
68
|
T extends ReadonlyArray<infer P> ? P : T,
|
|
69
|
-
|
|
69
|
+
IStyle
|
|
70
70
|
>;
|
|
71
71
|
|
|
72
72
|
export type IDefaultExtendableProps = IExtendableProps<'custom'>;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Classes } from 'jss';
|
|
2
|
-
import { IStyles } from '../types';
|
|
3
|
-
import { IPartialStyle } from './TweakStylesManager';
|
|
4
|
-
import { IJssContext } from './jss-context';
|
|
5
|
-
interface IThemedStylesManagerOptions<C extends string> {
|
|
6
|
-
styles: IStyles<C>;
|
|
7
|
-
name: string;
|
|
8
|
-
}
|
|
9
|
-
export declare class ThemedStylesManager<C extends string> {
|
|
10
|
-
#private;
|
|
11
|
-
constructor({ styles, name }: IThemedStylesManagerOptions<C>);
|
|
12
|
-
getClasses(theme: object | undefined, tweak: IPartialStyle[], jssContext: IJssContext): Classes<C>;
|
|
13
|
-
manageTweak(theme: object | undefined, tweak: IPartialStyle[]): VoidFunction | undefined;
|
|
14
|
-
manage(theme?: object): VoidFunction | undefined;
|
|
15
|
-
private unmanage;
|
|
16
|
-
private getOrCreate;
|
|
17
|
-
}
|
|
18
|
-
export {};
|