@dr.pogodin/react-utils 1.35.5 → 1.36.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/LICENSE.md +1 -1
- package/build/development/index.js +0 -6
- package/build/development/index.js.map +1 -1
- package/build/development/server/Cache.js +19 -19
- package/build/development/server/Cache.js.map +1 -1
- package/build/development/server/renderer.js +7 -4
- package/build/development/server/renderer.js.map +1 -1
- package/build/development/server/server.js +4 -1
- package/build/development/server/server.js.map +1 -1
- package/build/development/shared/components/Button/index.js +1 -16
- package/build/development/shared/components/Button/index.js.map +1 -1
- package/build/development/shared/components/Checkbox/index.js +1 -29
- package/build/development/shared/components/Checkbox/index.js.map +1 -1
- package/build/development/shared/components/GenericLink/index.js +0 -15
- package/build/development/shared/components/GenericLink/index.js.map +1 -1
- package/build/development/shared/components/Input/index.js +1 -8
- package/build/development/shared/components/Input/index.js.map +1 -1
- package/build/development/shared/components/MetaTags.js +0 -12
- package/build/development/shared/components/MetaTags.js.map +1 -1
- package/build/development/shared/components/Modal/index.js +2 -13
- package/build/development/shared/components/Modal/index.js.map +1 -1
- package/build/development/shared/components/PageLayout/index.js +1 -10
- package/build/development/shared/components/PageLayout/index.js.map +1 -1
- package/build/development/shared/components/TextArea/index.js +1 -12
- package/build/development/shared/components/TextArea/index.js.map +1 -1
- package/build/development/shared/components/Throbber/index.js +1 -6
- package/build/development/shared/components/Throbber/index.js.map +1 -1
- package/build/development/shared/components/WithTooltip/Tooltip.js +1 -8
- package/build/development/shared/components/WithTooltip/Tooltip.js.map +1 -1
- package/build/development/shared/components/WithTooltip/index.js +1 -9
- package/build/development/shared/components/WithTooltip/index.js.map +1 -1
- package/build/development/shared/components/YouTubeVideo/index.js +2 -11
- package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/Options/index.js +1 -16
- package/build/development/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/index.js +2 -12
- package/build/development/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/NativeDropdown/index.js +2 -12
- package/build/development/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/Switch/index.js +21 -28
- package/build/development/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/development/shared/components/selectors/common.js +0 -19
- package/build/development/shared/components/selectors/common.js.map +1 -1
- package/build/development/shared/components/selectors/index.js +0 -13
- package/build/development/shared/components/selectors/index.js.map +1 -1
- package/build/development/shared/utils/jest/index.js +4 -2
- package/build/development/shared/utils/jest/index.js.map +1 -1
- package/build/development/shared/utils/splitComponent.js +11 -12
- package/build/development/shared/utils/splitComponent.js.map +1 -1
- package/build/development/web.bundle.js +26 -36
- package/build/production/index.js +1 -1
- package/build/production/index.js.map +1 -1
- package/build/production/server/Cache.js +3 -3
- package/build/production/server/Cache.js.map +1 -1
- package/build/production/server/renderer.js +2 -2
- package/build/production/server/renderer.js.map +1 -1
- package/build/production/server/server.js +1 -1
- package/build/production/server/server.js.map +1 -1
- package/build/production/shared/components/Button/index.js +3 -3
- package/build/production/shared/components/Button/index.js.map +1 -1
- package/build/production/shared/components/Checkbox/index.js +1 -16
- package/build/production/shared/components/Checkbox/index.js.map +1 -1
- package/build/production/shared/components/GenericLink/index.js +2 -2
- package/build/production/shared/components/GenericLink/index.js.map +1 -1
- package/build/production/shared/components/Input/index.js +2 -2
- package/build/production/shared/components/Input/index.js.map +1 -1
- package/build/production/shared/components/MetaTags.js +2 -2
- package/build/production/shared/components/MetaTags.js.map +1 -1
- package/build/production/shared/components/Modal/index.js +2 -2
- package/build/production/shared/components/Modal/index.js.map +1 -1
- package/build/production/shared/components/PageLayout/index.js +2 -2
- package/build/production/shared/components/PageLayout/index.js.map +1 -1
- package/build/production/shared/components/TextArea/index.js +2 -2
- package/build/production/shared/components/TextArea/index.js.map +1 -1
- package/build/production/shared/components/Throbber/index.js +2 -2
- package/build/production/shared/components/Throbber/index.js.map +1 -1
- package/build/production/shared/components/WithTooltip/Tooltip.js +3 -3
- package/build/production/shared/components/WithTooltip/Tooltip.js.map +1 -1
- package/build/production/shared/components/WithTooltip/index.js +2 -2
- package/build/production/shared/components/WithTooltip/index.js.map +1 -1
- package/build/production/shared/components/YouTubeVideo/index.js +3 -3
- package/build/production/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/Options/index.js +2 -2
- package/build/production/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/index.js +2 -2
- package/build/production/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/production/shared/components/selectors/NativeDropdown/index.js +3 -3
- package/build/production/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/production/shared/components/selectors/Switch/index.js +1 -1
- package/build/production/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/production/shared/components/selectors/common.js +2 -4
- package/build/production/shared/components/selectors/common.js.map +1 -1
- package/build/production/shared/components/selectors/index.js +1 -1
- package/build/production/shared/components/selectors/index.js.map +1 -1
- package/build/production/shared/utils/jest/index.js +1 -1
- package/build/production/shared/utils/jest/index.js.map +1 -1
- package/build/production/shared/utils/splitComponent.js +5 -5
- package/build/production/shared/utils/splitComponent.js.map +1 -1
- package/build/production/web.bundle.js +1 -1
- package/build/production/web.bundle.js.map +1 -1
- package/build/types-code/index.d.ts +1 -2
- package/build/types-code/server/Cache.d.ts +3 -11
- package/build/types-code/server/index.d.ts +0 -2
- package/build/types-code/server/renderer.d.ts +0 -1
- package/build/types-code/server/server.d.ts +0 -1
- package/build/types-code/shared/components/Button/index.d.ts +3 -4
- package/build/types-code/shared/components/Checkbox/index.d.ts +3 -12
- package/build/types-code/shared/components/Input/index.d.ts +4 -5
- package/build/types-code/shared/components/Link.d.ts +0 -1
- package/build/types-code/shared/components/Modal/index.d.ts +3 -4
- package/build/types-code/shared/components/NavLink.d.ts +0 -1
- package/build/types-code/shared/components/PageLayout/index.d.ts +4 -4
- package/build/types-code/shared/components/TextArea/index.d.ts +4 -5
- package/build/types-code/shared/components/Throbber/index.d.ts +4 -4
- package/build/types-code/shared/components/WithTooltip/Tooltip.d.ts +1 -1
- package/build/types-code/shared/components/WithTooltip/index.d.ts +2 -3
- package/build/types-code/shared/components/YouTubeVideo/index.d.ts +3 -4
- package/build/types-code/shared/components/selectors/CustomDropdown/Options/index.d.ts +1 -2
- package/build/types-code/shared/components/selectors/CustomDropdown/index.d.ts +2 -3
- package/build/types-code/shared/components/selectors/NativeDropdown/index.d.ts +2 -2
- package/build/types-code/shared/components/selectors/Switch/index.d.ts +4 -5
- package/build/types-code/shared/components/selectors/common.d.ts +4 -10
- package/build/types-code/shared/components/selectors/index.d.ts +1 -1
- package/build/types-code/shared/utils/globalState.d.ts +1 -2
- package/build/types-code/shared/utils/jest/index.d.ts +4 -1
- package/build/types-code/shared/utils/splitComponent.d.ts +0 -1
- package/build/types-code/shared/utils/webpack.d.ts +0 -1
- package/config/babel/node-ssr.js +1 -1
- package/config/babel/webpack.js +1 -1
- package/config/eslint/default.json +1 -0
- package/config/eslint/jest.json +1 -0
- package/config/eslint/typescript.js +7 -0
- package/config/typescript/base.json +9 -0
- package/config/webpack/app-base.d.ts +0 -1
- package/config/webpack/app-base.js +1 -1
- package/config/webpack/app-development.js +1 -1
- package/config/webpack/app-production.js +1 -1
- package/config/webpack/lib-base.js +1 -2
- package/config/webpack/lib-development.js +1 -1
- package/config/webpack/lib-production.js +1 -1
- package/package.json +16 -17
- package/src/index.ts +0 -1
- package/src/server/Cache.ts +31 -30
- package/src/server/renderer.tsx +8 -5
- package/src/server/server.ts +6 -1
- package/src/shared/components/Button/index.tsx +2 -20
- package/src/shared/components/Checkbox/index.tsx +2 -37
- package/src/shared/components/GenericLink/index.tsx +0 -15
- package/src/shared/components/Input/index.tsx +6 -15
- package/src/shared/components/MetaTags.tsx +0 -12
- package/src/shared/components/Modal/index.tsx +3 -22
- package/src/shared/components/PageLayout/index.tsx +8 -24
- package/src/shared/components/TextArea/index.tsx +6 -24
- package/src/shared/components/Throbber/index.tsx +6 -18
- package/src/shared/components/WithTooltip/Tooltip.tsx +6 -14
- package/src/shared/components/WithTooltip/index.tsx +3 -24
- package/src/shared/components/YouTubeVideo/index.tsx +3 -20
- package/src/shared/components/selectors/CustomDropdown/Options/index.tsx +2 -20
- package/src/shared/components/selectors/CustomDropdown/index.tsx +3 -27
- package/src/shared/components/selectors/NativeDropdown/index.tsx +3 -27
- package/src/shared/components/selectors/Switch/index.tsx +34 -50
- package/src/shared/components/selectors/common.ts +12 -44
- package/src/shared/components/selectors/index.ts +0 -2
- package/src/shared/utils/jest/index.tsx +13 -2
- package/src/shared/utils/splitComponent.tsx +14 -11
- package/tsconfig.configs.json +7 -3
- package/tsconfig.json +3 -10
- package/tsconfig.types.json +1 -7
- package/tstyche.config.json +6 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/* global window */
|
|
2
2
|
|
|
3
|
-
import PT from 'prop-types';
|
|
4
3
|
import {
|
|
5
4
|
type ReactNode,
|
|
6
5
|
useEffect,
|
|
@@ -11,19 +10,17 @@ import {
|
|
|
11
10
|
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
12
11
|
|
|
13
12
|
import Tooltip, {
|
|
13
|
+
type ThemeKeysT as TooltipThemeKeysT,
|
|
14
14
|
PLACEMENTS,
|
|
15
|
-
validThemeKeys as validTooltipThemeKeys,
|
|
16
15
|
} from './Tooltip';
|
|
17
16
|
|
|
18
17
|
import defaultTheme from './default-theme.scss';
|
|
19
18
|
|
|
20
|
-
const validThemeKeys = [...validTooltipThemeKeys, 'wrapper'] as const;
|
|
21
|
-
|
|
22
19
|
type PropsT = {
|
|
23
20
|
children?: ReactNode;
|
|
24
21
|
placement?: PLACEMENTS;
|
|
25
22
|
tip?: ReactNode;
|
|
26
|
-
theme: Theme<
|
|
23
|
+
theme: Theme<'wrapper' | TooltipThemeKeysT>;
|
|
27
24
|
};
|
|
28
25
|
|
|
29
26
|
type TooltipRefT = {
|
|
@@ -170,18 +167,7 @@ const Wrapper: React.FunctionComponent<PropsT> = ({
|
|
|
170
167
|
);
|
|
171
168
|
};
|
|
172
169
|
|
|
173
|
-
const ThemedWrapper = themed(
|
|
174
|
-
Wrapper,
|
|
175
|
-
'WithTooltip',
|
|
176
|
-
[
|
|
177
|
-
'appearance',
|
|
178
|
-
'arrow',
|
|
179
|
-
'container',
|
|
180
|
-
'content',
|
|
181
|
-
'wrapper',
|
|
182
|
-
],
|
|
183
|
-
defaultTheme,
|
|
184
|
-
);
|
|
170
|
+
const ThemedWrapper = themed(Wrapper, 'WithTooltip', defaultTheme);
|
|
185
171
|
|
|
186
172
|
type ExportT = typeof ThemedWrapper & {
|
|
187
173
|
PLACEMENTS: typeof PLACEMENTS;
|
|
@@ -191,11 +177,4 @@ const e: ExportT = ThemedWrapper as ExportT;
|
|
|
191
177
|
|
|
192
178
|
e.PLACEMENTS = PLACEMENTS;
|
|
193
179
|
|
|
194
|
-
Wrapper.propTypes = {
|
|
195
|
-
children: PT.node,
|
|
196
|
-
placement: PT.oneOf(Object.values(PLACEMENTS)),
|
|
197
|
-
theme: ThemedWrapper.themeType.isRequired,
|
|
198
|
-
tip: PT.node,
|
|
199
|
-
};
|
|
200
|
-
|
|
201
180
|
export default e;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import PT from 'prop-types';
|
|
2
1
|
import qs from 'qs';
|
|
3
2
|
|
|
4
3
|
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
@@ -8,9 +7,7 @@ import Throbber from 'components/Throbber';
|
|
|
8
7
|
import baseTheme from './base.scss';
|
|
9
8
|
import throbberTheme from './throbber.scss';
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
type ComponentThemeT = Theme<typeof validThemeKeys>;
|
|
10
|
+
type ComponentThemeT = Theme<'container' | 'video'>;
|
|
14
11
|
|
|
15
12
|
type PropsT = {
|
|
16
13
|
autoplay?: boolean;
|
|
@@ -45,7 +42,7 @@ const YouTubeVideo: React.FunctionComponent<PropsT> = ({
|
|
|
45
42
|
const queryString = srcParts[1];
|
|
46
43
|
const query = queryString ? qs.parse(queryString) : {};
|
|
47
44
|
|
|
48
|
-
const videoId = query.v || url
|
|
45
|
+
const videoId = query.v || url?.match(/\/([a-zA-Z0-9-_]*)$/)?.[1];
|
|
49
46
|
url = `https://www.youtube.com/embed/${videoId}`;
|
|
50
47
|
|
|
51
48
|
delete query.v;
|
|
@@ -69,18 +66,4 @@ const YouTubeVideo: React.FunctionComponent<PropsT> = ({
|
|
|
69
66
|
);
|
|
70
67
|
};
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
YouTubeVideo,
|
|
74
|
-
'YouTubeVideo',
|
|
75
|
-
validThemeKeys,
|
|
76
|
-
baseTheme,
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
YouTubeVideo.propTypes = {
|
|
80
|
-
autoplay: PT.bool,
|
|
81
|
-
src: PT.string.isRequired,
|
|
82
|
-
theme: ThemedYouTubeVideo.themeType.isRequired,
|
|
83
|
-
title: PT.string,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export default ThemedYouTubeVideo;
|
|
69
|
+
export default themed(YouTubeVideo, 'YouTubeVideo', baseTheme);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import PT from 'prop-types';
|
|
2
1
|
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
|
3
2
|
|
|
4
3
|
import { BaseModal } from 'components/Modal';
|
|
@@ -9,7 +8,6 @@ import {
|
|
|
9
8
|
type OptionT,
|
|
10
9
|
type OptionsT,
|
|
11
10
|
type ValueT,
|
|
12
|
-
optionsValidator,
|
|
13
11
|
optionValueName,
|
|
14
12
|
} from '../../common';
|
|
15
13
|
|
|
@@ -32,7 +30,7 @@ type PropsT = {
|
|
|
32
30
|
containerStyle?: ContainerPosT;
|
|
33
31
|
filter?: (item: OptionT<React.ReactNode> | ValueT) => boolean;
|
|
34
32
|
optionClass: string;
|
|
35
|
-
options: OptionsT<React.ReactNode
|
|
33
|
+
options: Readonly<OptionsT<React.ReactNode>>;
|
|
36
34
|
onCancel: () => void;
|
|
37
35
|
onChange: (value: ValueT) => void;
|
|
38
36
|
};
|
|
@@ -67,7 +65,7 @@ const Options = forwardRef<RefT, PropsT>(({
|
|
|
67
65
|
const optionNodes: React.ReactNode[] = [];
|
|
68
66
|
for (let i = 0; i < options.length; ++i) {
|
|
69
67
|
const option = options[i];
|
|
70
|
-
if (!filter || filter(option)) {
|
|
68
|
+
if (option !== undefined && (!filter || filter(option))) {
|
|
71
69
|
const [iValue, iName] = optionValueName(option);
|
|
72
70
|
optionNodes.push(
|
|
73
71
|
<div
|
|
@@ -116,20 +114,4 @@ const Options = forwardRef<RefT, PropsT>(({
|
|
|
116
114
|
);
|
|
117
115
|
});
|
|
118
116
|
|
|
119
|
-
Options.propTypes = {
|
|
120
|
-
containerClass: PT.string.isRequired,
|
|
121
|
-
|
|
122
|
-
containerStyle: PT.shape({
|
|
123
|
-
left: PT.number.isRequired,
|
|
124
|
-
top: PT.number.isRequired,
|
|
125
|
-
width: PT.number.isRequired,
|
|
126
|
-
}),
|
|
127
|
-
|
|
128
|
-
filter: PT.func,
|
|
129
|
-
onCancel: PT.func.isRequired,
|
|
130
|
-
onChange: PT.func.isRequired,
|
|
131
|
-
optionClass: PT.string.isRequired,
|
|
132
|
-
options: optionsValidator.isRequired,
|
|
133
|
-
};
|
|
134
|
-
|
|
135
117
|
export default Options;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import PT from 'prop-types';
|
|
2
1
|
import { useEffect, useRef, useState } from 'react';
|
|
3
2
|
|
|
4
3
|
import themed from '@dr.pogodin/react-themes';
|
|
@@ -7,14 +6,7 @@ import Options, { type ContainerPosT, type RefT, areEqual } from './Options';
|
|
|
7
6
|
|
|
8
7
|
import defaultTheme from './theme.scss';
|
|
9
8
|
|
|
10
|
-
import {
|
|
11
|
-
type PropsT,
|
|
12
|
-
type ValueT,
|
|
13
|
-
optionValidator,
|
|
14
|
-
optionValueName,
|
|
15
|
-
validThemeKeys,
|
|
16
|
-
valueValidator,
|
|
17
|
-
} from '../common';
|
|
9
|
+
import { type PropsT, type ValueT, optionValueName } from '../common';
|
|
18
10
|
|
|
19
11
|
const BaseCustomDropdown: React.FunctionComponent<
|
|
20
12
|
PropsT<React.ReactNode, (value: ValueT) => void>
|
|
@@ -97,7 +89,7 @@ PropsT<React.ReactNode, (value: ValueT) => void>
|
|
|
97
89
|
let selected: React.ReactNode = <>‌</>;
|
|
98
90
|
for (let i = 0; i < options.length; ++i) {
|
|
99
91
|
const option = options[i];
|
|
100
|
-
if (!filter || filter(option)) {
|
|
92
|
+
if (option !== undefined && (!filter || filter(option))) {
|
|
101
93
|
const [iValue, iName] = optionValueName(option);
|
|
102
94
|
if (iValue === value) {
|
|
103
95
|
selected = iName;
|
|
@@ -155,20 +147,4 @@ PropsT<React.ReactNode, (value: ValueT) => void>
|
|
|
155
147
|
);
|
|
156
148
|
};
|
|
157
149
|
|
|
158
|
-
|
|
159
|
-
BaseCustomDropdown,
|
|
160
|
-
'CustomDropdown',
|
|
161
|
-
validThemeKeys,
|
|
162
|
-
defaultTheme,
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
BaseCustomDropdown.propTypes = {
|
|
166
|
-
filter: PT.func,
|
|
167
|
-
label: PT.node,
|
|
168
|
-
onChange: PT.func,
|
|
169
|
-
options: PT.arrayOf(optionValidator.isRequired),
|
|
170
|
-
theme: ThemedCustomDropdown.themeType.isRequired,
|
|
171
|
-
value: valueValidator,
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
export default ThemedCustomDropdown;
|
|
150
|
+
export default themed(BaseCustomDropdown, 'CustomDropdown', defaultTheme);
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
// Implements dropdown based on the native HTML <select> element.
|
|
2
2
|
|
|
3
|
-
import PT from 'prop-types';
|
|
4
|
-
|
|
5
3
|
import themed from '@dr.pogodin/react-themes';
|
|
6
4
|
|
|
7
5
|
import defaultTheme from './theme.scss';
|
|
8
6
|
|
|
9
|
-
import {
|
|
10
|
-
type PropsT,
|
|
11
|
-
optionValueName,
|
|
12
|
-
stringOptionsValidator,
|
|
13
|
-
validThemeKeys,
|
|
14
|
-
valueValidator,
|
|
15
|
-
} from '../common';
|
|
7
|
+
import { type PropsT, optionValueName } from '../common';
|
|
16
8
|
|
|
17
9
|
/**
|
|
18
10
|
* Implements a themeable dropdown list. Internally it is rendered with help of
|
|
@@ -48,7 +40,7 @@ const Dropdown: React.FunctionComponent<PropsT<string>> = ({
|
|
|
48
40
|
|
|
49
41
|
for (let i = 0; i < options.length; ++i) {
|
|
50
42
|
const option = options[i];
|
|
51
|
-
if (!filter || filter(option)) {
|
|
43
|
+
if (option !== undefined && (!filter || filter(option))) {
|
|
52
44
|
const [iValue, iName] = optionValueName(option);
|
|
53
45
|
isValidValue ||= iValue === value;
|
|
54
46
|
optionElements.push(
|
|
@@ -92,20 +84,4 @@ const Dropdown: React.FunctionComponent<PropsT<string>> = ({
|
|
|
92
84
|
);
|
|
93
85
|
};
|
|
94
86
|
|
|
95
|
-
|
|
96
|
-
Dropdown,
|
|
97
|
-
'Dropdown',
|
|
98
|
-
validThemeKeys,
|
|
99
|
-
defaultTheme,
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
Dropdown.propTypes = {
|
|
103
|
-
filter: PT.func,
|
|
104
|
-
label: PT.node,
|
|
105
|
-
onChange: PT.func,
|
|
106
|
-
options: stringOptionsValidator,
|
|
107
|
-
theme: ThemedDropdown.themeType.isRequired,
|
|
108
|
-
value: valueValidator,
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export default ThemedDropdown;
|
|
87
|
+
export default themed(Dropdown, 'Dropdown', defaultTheme);
|
|
@@ -1,29 +1,25 @@
|
|
|
1
|
-
import PT from 'prop-types';
|
|
2
1
|
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
3
2
|
|
|
4
3
|
import {
|
|
5
4
|
type OptionsT,
|
|
6
5
|
type ValueT,
|
|
7
|
-
optionsValidator,
|
|
8
6
|
optionValueName,
|
|
9
|
-
valueValidator,
|
|
10
7
|
} from '../common';
|
|
11
8
|
|
|
12
9
|
import defaultTheme from './theme.scss';
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
'container'
|
|
16
|
-
'label'
|
|
17
|
-
'option'
|
|
18
|
-
'options'
|
|
19
|
-
'selected'
|
|
20
|
-
] as const;
|
|
11
|
+
type ThemeKeyT =
|
|
12
|
+
| 'container'
|
|
13
|
+
| 'label'
|
|
14
|
+
| 'option'
|
|
15
|
+
| 'options'
|
|
16
|
+
| 'selected';
|
|
21
17
|
|
|
22
18
|
type PropsT = {
|
|
23
19
|
label?: React.ReactNode;
|
|
24
20
|
onChange?: (value: ValueT) => void;
|
|
25
21
|
options?: Readonly<OptionsT<React.ReactNode>>;
|
|
26
|
-
theme: Theme<
|
|
22
|
+
theme: Theme<ThemeKeyT>;
|
|
27
23
|
value?: ValueT;
|
|
28
24
|
};
|
|
29
25
|
|
|
@@ -38,31 +34,34 @@ const BaseSwitch: React.FunctionComponent<PropsT> = ({
|
|
|
38
34
|
|
|
39
35
|
const optionNodes: React.ReactNode[] = [];
|
|
40
36
|
for (let i = 0; i < options?.length; ++i) {
|
|
41
|
-
const
|
|
37
|
+
const option = options[i];
|
|
38
|
+
if (option !== undefined) {
|
|
39
|
+
const [iValue, iName] = optionValueName(option);
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
let className: string = theme.option;
|
|
42
|
+
let onPress: (() => void) | undefined;
|
|
43
|
+
if (iValue === value) className += ` ${theme.selected}`;
|
|
44
|
+
else if (onChange) onPress = () => onChange(iValue);
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
46
|
+
optionNodes.push(
|
|
47
|
+
onPress ? (
|
|
48
|
+
<div
|
|
49
|
+
className={className}
|
|
50
|
+
onClick={onPress}
|
|
51
|
+
onKeyDown={(e) => {
|
|
52
|
+
if (onPress && e.key === 'Enter') onPress();
|
|
53
|
+
}}
|
|
54
|
+
key={iValue}
|
|
55
|
+
role="button"
|
|
56
|
+
tabIndex={0}
|
|
57
|
+
>
|
|
58
|
+
{iName}
|
|
59
|
+
</div>
|
|
60
|
+
) : (
|
|
61
|
+
<div className={className} key={iValue}>{iName}</div>
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
return (
|
|
@@ -75,19 +74,4 @@ const BaseSwitch: React.FunctionComponent<PropsT> = ({
|
|
|
75
74
|
);
|
|
76
75
|
};
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
BaseSwitch,
|
|
80
|
-
'Switch',
|
|
81
|
-
validThemeKeys,
|
|
82
|
-
defaultTheme,
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
BaseSwitch.propTypes = {
|
|
86
|
-
label: PT.node,
|
|
87
|
-
onChange: PT.func,
|
|
88
|
-
options: optionsValidator,
|
|
89
|
-
theme: ThemedSwitch.themeType.isRequired,
|
|
90
|
-
value: valueValidator,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export default ThemedSwitch;
|
|
77
|
+
export default themed(BaseSwitch, 'Switch', defaultTheme);
|
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
// The stuff common between different dropdown implementations.
|
|
2
2
|
|
|
3
|
-
import PT from 'prop-types';
|
|
4
|
-
|
|
5
3
|
import type { Theme } from '@dr.pogodin/react-themes';
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
'active'
|
|
9
|
-
'arrow'
|
|
10
|
-
'container'
|
|
11
|
-
'dropdown'
|
|
12
|
-
'hiddenOption'
|
|
13
|
-
'label'
|
|
14
|
-
'option'
|
|
15
|
-
'select'
|
|
5
|
+
type ThemeKeyT =
|
|
6
|
+
| 'active'
|
|
7
|
+
| 'arrow'
|
|
8
|
+
| 'container'
|
|
9
|
+
| 'dropdown'
|
|
10
|
+
| 'hiddenOption'
|
|
11
|
+
| 'label'
|
|
12
|
+
| 'option'
|
|
13
|
+
| 'select'
|
|
16
14
|
|
|
17
15
|
// TODO: This is only valid for <CustomDropdown>, thus we need to re-factor it
|
|
18
16
|
// into a separate theme spec for that component.
|
|
19
|
-
'upward'
|
|
20
|
-
] as const;
|
|
17
|
+
| 'upward';
|
|
21
18
|
|
|
22
19
|
export type ValueT = number | string;
|
|
23
20
|
|
|
24
|
-
export const valueValidator: PT.Requireable<ValueT> = PT.oneOfType([
|
|
25
|
-
PT.number.isRequired,
|
|
26
|
-
PT.string.isRequired,
|
|
27
|
-
]);
|
|
28
|
-
|
|
29
21
|
export type OptionT<NameT> = {
|
|
30
22
|
name?: NameT | null;
|
|
31
23
|
value: ValueT;
|
|
@@ -40,35 +32,11 @@ export type PropsT<
|
|
|
40
32
|
filter?: (item: OptionT<NameT> | ValueT) => boolean;
|
|
41
33
|
label?: React.ReactNode;
|
|
42
34
|
onChange?: OnChangeT;
|
|
43
|
-
options?: OptionsT<NameT
|
|
44
|
-
theme: Theme<
|
|
35
|
+
options?: Readonly<OptionsT<NameT>>;
|
|
36
|
+
theme: Theme<ThemeKeyT>;
|
|
45
37
|
value?: ValueT;
|
|
46
38
|
};
|
|
47
39
|
|
|
48
|
-
export const optionValidator:
|
|
49
|
-
PT.Requireable<OptionT<React.ReactNode> | ValueT> = PT.oneOfType([
|
|
50
|
-
PT.shape({
|
|
51
|
-
name: PT.node,
|
|
52
|
-
value: valueValidator.isRequired,
|
|
53
|
-
}).isRequired,
|
|
54
|
-
PT.number.isRequired,
|
|
55
|
-
PT.string.isRequired,
|
|
56
|
-
]);
|
|
57
|
-
|
|
58
|
-
export const optionsValidator = PT.arrayOf(optionValidator.isRequired);
|
|
59
|
-
|
|
60
|
-
export const stringOptionValidator:
|
|
61
|
-
PT.Requireable<OptionT<string> | ValueT> = PT.oneOfType([
|
|
62
|
-
PT.shape({
|
|
63
|
-
name: PT.string,
|
|
64
|
-
value: valueValidator.isRequired,
|
|
65
|
-
}).isRequired,
|
|
66
|
-
PT.number.isRequired,
|
|
67
|
-
PT.string.isRequired,
|
|
68
|
-
]);
|
|
69
|
-
|
|
70
|
-
export const stringOptionsValidator = PT.arrayOf(stringOptionValidator.isRequired);
|
|
71
|
-
|
|
72
40
|
function isValue<T>(x: OptionT<T> | ValueT): x is ValueT {
|
|
73
41
|
const type = typeof x;
|
|
74
42
|
return type === 'number' || type === 'string';
|
|
@@ -100,12 +100,23 @@ export function mount(scene: ReactNode): MountedSceneT {
|
|
|
100
100
|
return res;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
type SnapshotOptionsT = {
|
|
104
|
+
await?: Promise<void>;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export async function snapshot(
|
|
108
|
+
element: React.ReactElement,
|
|
109
|
+
options?: SnapshotOptionsT,
|
|
110
|
+
) {
|
|
104
111
|
let res: RenderResult | undefined;
|
|
105
|
-
|
|
112
|
+
|
|
113
|
+
const promise = act(() => {
|
|
106
114
|
res = render(element);
|
|
115
|
+
return options?.await;
|
|
107
116
|
});
|
|
117
|
+
|
|
108
118
|
if (res === undefined) throw Error('Render failed');
|
|
119
|
+
if (options?.await) await promise;
|
|
109
120
|
|
|
110
121
|
const nodes = res.asFragment().childNodes;
|
|
111
122
|
expect(nodes.length > 1 ? [...nodes] : nodes[0]).toMatchSnapshot();
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/* eslint-disable react/jsx-props-no-spreading */
|
|
2
2
|
/* global document */
|
|
3
3
|
|
|
4
|
-
import PT from 'prop-types';
|
|
5
|
-
|
|
6
4
|
import {
|
|
7
5
|
type ComponentType,
|
|
8
6
|
type ReactNode,
|
|
@@ -88,7 +86,7 @@ function getLoadedStyleSheets(): Set<string> {
|
|
|
88
86
|
const res = new Set<string>();
|
|
89
87
|
const { styleSheets } = document;
|
|
90
88
|
for (let i = 0; i < styleSheets.length; ++i) {
|
|
91
|
-
const
|
|
89
|
+
const href = styleSheets[i]?.href;
|
|
92
90
|
if (href) res.add(href);
|
|
93
91
|
}
|
|
94
92
|
return res;
|
|
@@ -118,11 +116,13 @@ export function bookStyleSheets(
|
|
|
118
116
|
): Promise<void> {
|
|
119
117
|
const promises = [];
|
|
120
118
|
const assets = chunkGroups[chunkName];
|
|
119
|
+
if (!assets) return Promise.resolve();
|
|
120
|
+
|
|
121
121
|
const loadedSheets = getLoadedStyleSheets();
|
|
122
122
|
|
|
123
123
|
for (let i = 0; i < assets.length; ++i) {
|
|
124
124
|
const asset = assets[i];
|
|
125
|
-
if (asset
|
|
125
|
+
if (asset?.endsWith('.css')) {
|
|
126
126
|
const promise = bookStyleSheet(asset, loadedSheets, refCount);
|
|
127
127
|
if (promise) promises.push(promise);
|
|
128
128
|
}
|
|
@@ -145,12 +145,19 @@ export function freeStyleSheets(
|
|
|
145
145
|
chunkGroups: ChunkGroupsT,
|
|
146
146
|
) {
|
|
147
147
|
const assets = chunkGroups[chunkName];
|
|
148
|
+
if (!assets) return;
|
|
149
|
+
|
|
148
150
|
for (let i = 0; i < assets.length; ++i) {
|
|
149
151
|
const asset = assets[i];
|
|
150
|
-
if (asset
|
|
152
|
+
if (asset?.endsWith('.css')) {
|
|
151
153
|
const path = `${getPublicPath()}/${asset}`;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
|
|
155
|
+
const pathRefCount = refCounts[path];
|
|
156
|
+
if (pathRefCount) {
|
|
157
|
+
if (pathRefCount <= 1) {
|
|
158
|
+
document.head.querySelector(`link[href="${path}"]`)!.remove();
|
|
159
|
+
delete refCounts[path];
|
|
160
|
+
} else refCounts[path] = pathRefCount - 1;
|
|
154
161
|
}
|
|
155
162
|
}
|
|
156
163
|
}
|
|
@@ -243,9 +250,5 @@ export default function splitComponent<
|
|
|
243
250
|
</Suspense>
|
|
244
251
|
);
|
|
245
252
|
|
|
246
|
-
CodeSplit.propTypes = {
|
|
247
|
-
children: PT.node,
|
|
248
|
-
} as PT.WeakValidationMap<ComponentPropsT>;
|
|
249
|
-
|
|
250
253
|
return CodeSplit;
|
|
251
254
|
}
|
package/tsconfig.configs.json
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
// TS configuration for configs pre-building from TS sources.
|
|
2
2
|
|
|
3
3
|
{
|
|
4
|
-
"extends": "
|
|
4
|
+
"extends": "./config/typescript/base.json",
|
|
5
5
|
"include": [
|
|
6
6
|
"config-ts-src",
|
|
7
7
|
],
|
|
8
8
|
"compilerOptions": {
|
|
9
9
|
"declaration": true,
|
|
10
|
-
"jsx": "react-jsx",
|
|
11
10
|
"rootDir": "config-ts-src",
|
|
12
11
|
"outDir": "config",
|
|
13
12
|
"paths": {
|
|
14
13
|
"*": ["./src/shared/*", "./src/*", "./*"]
|
|
15
14
|
},
|
|
16
|
-
|
|
15
|
+
|
|
16
|
+
// TODO: Overriding the base config as configs are compiled into CommonJS
|
|
17
|
+
// modules, and this flag leads to the following error in that case, if set:
|
|
18
|
+
// ESM syntax is not allowed in a CommonJS module when 'verbatimModuleSyntax' is enabled.
|
|
19
|
+
// Perhaps, there is a better workaround?
|
|
20
|
+
"verbatimModuleSyntax": false
|
|
17
21
|
}
|
|
18
22
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
// TS config for ESLint, editor plugins, and other tools that look-up and use
|
|
2
2
|
// the default tsconfig.json file.
|
|
3
3
|
{
|
|
4
|
-
//
|
|
5
|
-
// resolution mechanics.
|
|
6
|
-
"extends": "./
|
|
4
|
+
// Relative path, as some tools relying on this config do not support Node's
|
|
5
|
+
// module resolution mechanics.
|
|
6
|
+
"extends": "./config/typescript/base.json",
|
|
7
7
|
|
|
8
8
|
"compilerOptions": {
|
|
9
|
-
"jsx": "react-jsx",
|
|
10
|
-
|
|
11
9
|
// BEWARE: Different settings are likely to transform dynamic import()
|
|
12
10
|
// statements in the code, thus breaking Webpack's code splitting.
|
|
13
11
|
// See: https://davidea.st/articles/webpack-typescript-code-split-wont-work
|
|
@@ -18,10 +16,5 @@
|
|
|
18
16
|
"*": ["./src/shared/*", "./src/*", "./*"]
|
|
19
17
|
},
|
|
20
18
|
"rootDirs": [".", "build/types-scss"],
|
|
21
|
-
"strict": true,
|
|
22
|
-
|
|
23
|
-
// This ensures TypeScript does not remove unused imports, which may cause
|
|
24
|
-
// troubles when we rely on some side-effects from imported modules.
|
|
25
|
-
"verbatimModuleSyntax": true,
|
|
26
19
|
}
|
|
27
20
|
}
|
package/tsconfig.types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// TS config for ESLint, editor plugins, and other tools that look-up and use
|
|
2
2
|
// the default tsconfig.json file.
|
|
3
3
|
{
|
|
4
|
-
"extends": "
|
|
4
|
+
"extends": "./config/typescript/base.json",
|
|
5
5
|
|
|
6
6
|
// Keep these in case any mocks / tests are declared within "src" code tree.
|
|
7
7
|
"exclude": [
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
"compilerOptions": {
|
|
17
17
|
"declaration": true,
|
|
18
18
|
"emitDeclarationOnly": true,
|
|
19
|
-
"jsx": "react-jsx",
|
|
20
19
|
|
|
21
20
|
// BEWARE: Different settings are likely to transform dynamic import()
|
|
22
21
|
// statements in the code, thus breaking Webpack's code splitting.
|
|
@@ -42,10 +41,5 @@
|
|
|
42
41
|
"utils/*": ["./src/shared/utils/*"],
|
|
43
42
|
},
|
|
44
43
|
"rootDirs": [".", "build/types-scss"],
|
|
45
|
-
"strict": true,
|
|
46
|
-
|
|
47
|
-
// This ensures TypeScript does not remove unused imports, which may cause
|
|
48
|
-
// troubles when we rely on some side-effects from imported modules.
|
|
49
|
-
"verbatimModuleSyntax": true,
|
|
50
44
|
},
|
|
51
45
|
}
|