@dr.pogodin/react-utils 1.30.2 → 1.31.0
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/bin/build.js +5 -0
- package/build/development/client/index.js +1 -1
- package/build/development/client/index.js.map +1 -1
- package/build/development/index.js +7 -0
- package/build/development/index.js.map +1 -1
- package/build/development/shared/components/Checkbox/index.js +2 -2
- package/build/development/shared/components/Checkbox/index.js.map +1 -1
- package/build/development/shared/components/Input/index.js +2 -2
- package/build/development/shared/components/Input/index.js.map +1 -1
- package/build/development/shared/components/Modal/index.js +25 -5
- package/build/development/shared/components/Modal/index.js.map +1 -1
- package/build/development/shared/components/TextArea/index.js +5 -0
- package/build/development/shared/components/TextArea/index.js.map +1 -1
- package/build/development/shared/components/YouTubeVideo/index.js +1 -3
- package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/development/shared/components/index.js +27 -14
- package/build/development/shared/components/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/Options/index.js +93 -0
- package/build/development/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -0
- package/build/development/shared/components/selectors/CustomDropdown/index.js +105 -0
- package/build/development/shared/components/selectors/CustomDropdown/index.js.map +1 -0
- package/build/development/shared/components/{Dropdown → selectors/NativeDropdown}/index.js +25 -34
- package/build/development/shared/components/selectors/NativeDropdown/index.js.map +1 -0
- package/build/development/shared/components/selectors/Switch/index.js +76 -0
- package/build/development/shared/components/selectors/Switch/index.js.map +1 -0
- package/build/development/shared/components/selectors/common.js +24 -0
- package/build/development/shared/components/selectors/common.js.map +1 -0
- package/build/development/shared/components/selectors/index.js +28 -0
- package/build/development/shared/components/selectors/index.js.map +1 -0
- package/build/development/style.css +387 -225
- package/build/development/web.bundle.js +109 -49
- package/build/production/client/index.js +1 -1
- package/build/production/client/index.js.map +1 -1
- package/build/production/index.js +1 -1
- package/build/production/index.js.map +1 -1
- package/build/production/shared/components/Checkbox/index.js +2 -2
- package/build/production/shared/components/Checkbox/index.js.map +1 -1
- package/build/production/shared/components/Input/index.js +1 -1
- package/build/production/shared/components/Input/index.js.map +1 -1
- package/build/production/shared/components/Modal/index.js +3 -2
- package/build/production/shared/components/Modal/index.js.map +1 -1
- package/build/production/shared/components/TextArea/index.js +3 -3
- package/build/production/shared/components/TextArea/index.js.map +1 -1
- package/build/production/shared/components/YouTubeVideo/index.js +2 -2
- package/build/production/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/production/shared/components/index.js +1 -1
- package/build/production/shared/components/index.js.map +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/Options/index.js +7 -0
- package/build/production/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -0
- package/build/production/shared/components/selectors/CustomDropdown/index.js +4 -0
- package/build/production/shared/components/selectors/CustomDropdown/index.js.map +1 -0
- package/build/production/shared/components/selectors/NativeDropdown/index.js +25 -0
- package/build/production/shared/components/selectors/NativeDropdown/index.js.map +1 -0
- package/build/production/shared/components/selectors/Switch/index.js +2 -0
- package/build/production/shared/components/selectors/Switch/index.js.map +1 -0
- package/build/production/shared/components/selectors/common.js +3 -0
- package/build/production/shared/components/selectors/common.js.map +1 -0
- package/build/production/shared/components/selectors/index.js +2 -0
- package/build/production/shared/components/selectors/index.js.map +1 -0
- package/build/production/style.css +1 -1
- package/build/production/style.css.map +1 -1
- package/build/production/web.bundle.js +1 -1
- package/build/production/web.bundle.js.map +1 -1
- package/build/types-code/client/index.d.ts +1 -0
- package/build/types-code/index.d.ts +1 -1
- package/build/types-code/shared/components/Checkbox/index.d.ts +1 -1
- package/build/types-code/shared/components/Input/index.d.ts +1 -1
- package/build/types-code/shared/components/Modal/index.d.ts +2 -1
- package/build/types-code/shared/components/TextArea/index.d.ts +1 -0
- package/build/types-code/shared/components/index.d.ts +1 -2
- package/build/types-code/shared/components/selectors/CustomDropdown/Options/index.d.ts +17 -0
- package/build/types-code/shared/components/selectors/CustomDropdown/index.d.ts +4 -0
- package/build/types-code/shared/components/selectors/NativeDropdown/index.d.ts +3 -0
- package/build/types-code/shared/components/selectors/Switch/index.d.ts +13 -0
- package/build/types-code/shared/components/selectors/common.d.ts +27 -0
- package/build/types-code/shared/components/selectors/index.d.ts +3 -0
- package/build/types-scss/src/shared/components/Modal/styles.scss.d.ts +1 -0
- package/build/types-scss/src/shared/components/selectors/CustomDropdown/Options/style.scss.d.ts +1 -0
- package/build/types-scss/src/shared/components/selectors/CustomDropdown/theme.scss.d.ts +10 -0
- package/build/types-scss/src/shared/components/{Dropdown → selectors/NativeDropdown}/theme.scss.d.ts +1 -0
- package/build/types-scss/src/shared/components/selectors/Switch/theme.scss.d.ts +6 -0
- package/package.json +6 -6
- package/src/client/index.tsx +2 -1
- package/src/index.ts +1 -0
- package/src/shared/components/Button/style.scss +1 -0
- package/src/shared/components/Checkbox/index.tsx +3 -3
- package/src/shared/components/Input/index.tsx +3 -3
- package/src/shared/components/Modal/base-theme.scss +1 -1
- package/src/shared/components/Modal/index.tsx +24 -5
- package/src/shared/components/Modal/styles.scss +2 -4
- package/src/shared/components/TextArea/index.tsx +5 -0
- package/src/shared/components/TextArea/style.scss +8 -0
- package/src/shared/components/YouTubeVideo/base.scss +3 -1
- package/src/shared/components/YouTubeVideo/index.tsx +2 -3
- package/src/shared/components/index.ts +2 -2
- package/src/shared/components/selectors/CustomDropdown/Options/index.tsx +117 -0
- package/src/shared/components/selectors/CustomDropdown/Options/style.scss +6 -0
- package/src/shared/components/selectors/CustomDropdown/index.tsx +115 -0
- package/src/shared/components/selectors/CustomDropdown/theme.scss +90 -0
- package/src/shared/components/{Dropdown → selectors/NativeDropdown}/index.tsx +21 -50
- package/src/shared/components/{Dropdown → selectors/NativeDropdown}/theme.scss +5 -0
- package/src/shared/components/selectors/Switch/index.tsx +94 -0
- package/src/shared/components/selectors/Switch/theme.scss +39 -0
- package/src/shared/components/selectors/common.ts +54 -0
- package/src/shared/components/selectors/index.ts +3 -0
- package/build/development/shared/components/Dropdown/index.js.map +0 -1
- package/build/development/shared/components/ScalableRect/index.js +0 -80
- package/build/development/shared/components/ScalableRect/index.js.map +0 -1
- package/build/production/shared/components/Dropdown/index.js +0 -24
- package/build/production/shared/components/Dropdown/index.js.map +0 -1
- package/build/production/shared/components/ScalableRect/index.js +0 -21
- package/build/production/shared/components/ScalableRect/index.js.map +0 -1
- package/build/types-code/shared/components/Dropdown/index.d.ts +0 -17
- package/build/types-code/shared/components/ScalableRect/index.d.ts +0 -19
- package/build/types-scss/src/shared/components/ScalableRect/style.scss.d.ts +0 -2
- package/src/shared/components/ScalableRect/index.tsx +0 -84
- package/src/shared/components/ScalableRect/style.scss +0 -10
|
@@ -4,7 +4,7 @@ declare const server: typeof ServerT | null;
|
|
|
4
4
|
declare const client: any;
|
|
5
5
|
export { default as api } from 'axios';
|
|
6
6
|
export * as PT from 'prop-types';
|
|
7
|
-
export { type AsyncCollectionLoaderT, type AsyncDataEnvelopeT, type AsyncDataLoaderT, type ForceT, type UseAsyncDataOptionsT, type UseAsyncDataResT, type UseGlobalStateResT, type ValueOrInitializerT, getGlobalState, GlobalStateProvider, useAsyncCollection, useAsyncData, useGlobalState, withGlobalStateType, } from '@dr.pogodin/react-global-state';
|
|
7
|
+
export { type AsyncCollectionLoaderT, type AsyncDataEnvelopeT, type AsyncDataLoaderT, type ForceT, type UseAsyncDataOptionsT, type UseAsyncDataResT, type UseGlobalStateResT, type ValueOrInitializerT, getGlobalState, GlobalStateProvider, newAsyncDataEnvelope, useAsyncCollection, useAsyncData, useGlobalState, withGlobalStateType, } from '@dr.pogodin/react-global-state';
|
|
8
8
|
export * from './shared/components';
|
|
9
9
|
export { type Theme, config, Barrier, Emitter, isomorphy, getSsrContext, JU, Semaphore, splitComponent, themed, ThemeProvider, time, webpack, withRetries, } from './shared/utils';
|
|
10
10
|
export { client, server };
|
|
@@ -3,7 +3,7 @@ import { type Theme } from '@dr.pogodin/react-themes';
|
|
|
3
3
|
declare const validThemeKeys: readonly ["checkbox", "container", "label"];
|
|
4
4
|
type PropT = {
|
|
5
5
|
checked?: boolean;
|
|
6
|
-
label?:
|
|
6
|
+
label?: React.ReactNode;
|
|
7
7
|
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
8
8
|
theme: Theme<typeof validThemeKeys>;
|
|
9
9
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { type Theme } from '@dr.pogodin/react-themes';
|
|
3
3
|
declare const validThemeKeys: readonly ["container", "input", "label"];
|
|
4
4
|
declare const ThemedInput: import("@dr.pogodin/react-themes").ThemedComponent<React.InputHTMLAttributes<HTMLInputElement> & {
|
|
5
|
-
label?:
|
|
5
|
+
label?: React.ReactNode;
|
|
6
6
|
theme: Theme<typeof validThemeKeys>;
|
|
7
7
|
} & React.RefAttributes<HTMLInputElement>>;
|
|
8
8
|
export default ThemedInput;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
import { type Theme } from '@dr.pogodin/react-themes';
|
|
3
|
-
import './styles.scss';
|
|
4
3
|
declare const validThemeKeys: readonly ["container", "overlay"];
|
|
5
4
|
type PropsT = {
|
|
6
5
|
children?: ReactNode;
|
|
6
|
+
containerStyle?: React.CSSProperties;
|
|
7
|
+
dontDisableScrolling?: boolean;
|
|
7
8
|
onCancel?: () => void;
|
|
8
9
|
theme: Theme<typeof validThemeKeys>;
|
|
9
10
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { type Theme } from '@dr.pogodin/react-themes';
|
|
3
3
|
declare const validThemeKeys: readonly ["container", "hidden", "textarea"];
|
|
4
4
|
type Props = {
|
|
5
|
+
disabled?: boolean;
|
|
5
6
|
onChange?: React.ChangeEventHandler<HTMLTextAreaElement>;
|
|
6
7
|
onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>;
|
|
7
8
|
placeholder?: string;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Just an aggregation of all exported components into a single module.
|
|
3
3
|
*/
|
|
4
|
+
export * from './selectors';
|
|
4
5
|
export { default as Button } from './Button';
|
|
5
6
|
export { default as Checkbox } from './Checkbox';
|
|
6
|
-
export { default as Dropdown } from './Dropdown';
|
|
7
7
|
export { default as Input } from './Input';
|
|
8
8
|
export { default as Link } from './Link';
|
|
9
9
|
export { default as PageLayout } from './PageLayout';
|
|
10
10
|
export { default as MetaTags } from './MetaTags';
|
|
11
11
|
export { default as Modal, BaseModal } from './Modal';
|
|
12
12
|
export { default as NavLink } from './NavLink';
|
|
13
|
-
export { default as ScalableRect } from './ScalableRect';
|
|
14
13
|
export { default as Throbber } from './Throbber';
|
|
15
14
|
export { default as WithTooltip } from './WithTooltip';
|
|
16
15
|
export { default as YouTubeVideo } from './YouTubeVideo';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { type OptionT, type OptionsT } from '../../common';
|
|
3
|
+
type PropsT = {
|
|
4
|
+
anchorRect: {
|
|
5
|
+
bottom: number;
|
|
6
|
+
left: number;
|
|
7
|
+
width: number;
|
|
8
|
+
};
|
|
9
|
+
containerClass: string;
|
|
10
|
+
filter?: (item: OptionT<React.ReactNode> | string) => boolean;
|
|
11
|
+
optionClass: string;
|
|
12
|
+
options: OptionsT<React.ReactNode>;
|
|
13
|
+
onCancel: () => void;
|
|
14
|
+
onChange: (value: string) => void;
|
|
15
|
+
};
|
|
16
|
+
declare const Options: React.FunctionComponent<PropsT>;
|
|
17
|
+
export default Options;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { type Theme } from '@dr.pogodin/react-themes';
|
|
3
|
+
import { type OptionsT } from '../common';
|
|
4
|
+
declare const validThemeKeys: readonly ["container", "label", "option", "selected", "switch"];
|
|
5
|
+
type PropsT = {
|
|
6
|
+
label?: React.ReactNode;
|
|
7
|
+
onChange?: (value: string) => void;
|
|
8
|
+
options?: Readonly<OptionsT<React.ReactNode>>;
|
|
9
|
+
theme: Theme<typeof validThemeKeys>;
|
|
10
|
+
value?: string;
|
|
11
|
+
};
|
|
12
|
+
declare const ThemedSwitch: import("@dr.pogodin/react-themes").ThemedComponent<PropsT>;
|
|
13
|
+
export default ThemedSwitch;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import PT from 'prop-types';
|
|
3
|
+
import type { Theme } from '@dr.pogodin/react-themes';
|
|
4
|
+
export declare const validThemeKeys: readonly ["active", "arrow", "container", "dropdown", "hiddenOption", "label", "option", "select"];
|
|
5
|
+
export type OptionT<NameT> = {
|
|
6
|
+
name?: NameT | null;
|
|
7
|
+
value: string;
|
|
8
|
+
};
|
|
9
|
+
export type OptionsT<NameT> = Array<OptionT<NameT> | string>;
|
|
10
|
+
export type PropsT<NameT, OnChangeT = React.ChangeEventHandler<HTMLSelectElement>> = {
|
|
11
|
+
filter?: (item: OptionT<NameT> | string) => boolean;
|
|
12
|
+
label?: React.ReactNode;
|
|
13
|
+
onChange?: OnChangeT;
|
|
14
|
+
options?: OptionsT<NameT>;
|
|
15
|
+
theme: Theme<typeof validThemeKeys>;
|
|
16
|
+
value?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const optionValidator: PT.Requireable<NonNullable<string | NonNullable<PT.InferProps<{
|
|
19
|
+
name: PT.Requireable<string>;
|
|
20
|
+
value: PT.Validator<string>;
|
|
21
|
+
}>>>>;
|
|
22
|
+
export declare const optionsValidator: PT.Requireable<NonNullable<NonNullable<string | NonNullable<PT.InferProps<{
|
|
23
|
+
name: PT.Requireable<string>;
|
|
24
|
+
value: PT.Validator<string>;
|
|
25
|
+
}>>>>[]>;
|
|
26
|
+
/** Returns option value and name as a tuple. */
|
|
27
|
+
export declare function optionValueName<NameT>(option: OptionT<NameT> | string): [string, NameT | string];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const scrollingDisabledByModal: string;
|
package/build/types-scss/src/shared/components/selectors/CustomDropdown/Options/style.scss.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const overlay: string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const active: string;
|
|
2
|
+
export declare const ad: string;
|
|
3
|
+
export declare const arrow: string;
|
|
4
|
+
export declare const container: string;
|
|
5
|
+
export declare const context: string;
|
|
6
|
+
export declare const dropdown: string;
|
|
7
|
+
export declare const hoc: string;
|
|
8
|
+
export declare const label: string;
|
|
9
|
+
export declare const option: string;
|
|
10
|
+
export declare const select: string;
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.31.0",
|
|
3
3
|
"bin": {
|
|
4
4
|
"react-utils-build": "bin/build.js",
|
|
5
5
|
"react-utils-setup": "bin/setup.js"
|
|
@@ -69,12 +69,12 @@
|
|
|
69
69
|
"@types/csurf": "^1.11.5",
|
|
70
70
|
"@types/express": "^4.17.21",
|
|
71
71
|
"@types/jest": "^29.5.12",
|
|
72
|
-
"@types/lodash": "^4.
|
|
72
|
+
"@types/lodash": "^4.17.0",
|
|
73
73
|
"@types/morgan": "^1.9.9",
|
|
74
74
|
"@types/node-forge": "^1.3.11",
|
|
75
75
|
"@types/pretty": "^2.0.3",
|
|
76
|
-
"@types/react": "^18.2.
|
|
77
|
-
"@types/react-dom": "^18.2.
|
|
76
|
+
"@types/react": "^18.2.66",
|
|
77
|
+
"@types/react-dom": "^18.2.22",
|
|
78
78
|
"@types/react-helmet": "^6.1.11",
|
|
79
79
|
"@types/react-test-renderer": "^18.0.7",
|
|
80
80
|
"@types/request-ip": "^0.0.41",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"react-test-renderer": "^18.2.0",
|
|
115
115
|
"regenerator-runtime": "^0.14.1",
|
|
116
116
|
"resolve-url-loader": "^5.0.0",
|
|
117
|
-
"sass": "^1.
|
|
117
|
+
"sass": "^1.72.0",
|
|
118
118
|
"sass-loader": "^14.1.1",
|
|
119
119
|
"sitemap": "^7.1.1",
|
|
120
120
|
"stylelint": "^16.2.1",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"tsc-alias": "^1.8.8",
|
|
124
124
|
"typed-scss-modules": "^8.0.0",
|
|
125
125
|
"typescript": "^5.4.2",
|
|
126
|
-
"typescript-eslint": "^7.
|
|
126
|
+
"typescript-eslint": "^7.2.0",
|
|
127
127
|
"webpack": "^5.90.3",
|
|
128
128
|
"webpack-dev-middleware": "^7.0.0",
|
|
129
129
|
"webpack-hot-middleware": "^2.26.1",
|
package/src/client/index.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import getInj from './getInj';
|
|
|
12
12
|
|
|
13
13
|
type OptionsT = {
|
|
14
14
|
dontHydrate?: boolean;
|
|
15
|
+
initialState?: any;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -26,7 +27,7 @@ export default function Launch(
|
|
|
26
27
|
const container = document.getElementById('react-view');
|
|
27
28
|
if (!container) throw Error('Failed to find container for React app');
|
|
28
29
|
const scene = (
|
|
29
|
-
<GlobalStateProvider initialState={getInj().ISTATE}>
|
|
30
|
+
<GlobalStateProvider initialState={getInj().ISTATE || options.initialState}>
|
|
30
31
|
<BrowserRouter future={{ v7_relativeSplatPath: true }}>
|
|
31
32
|
<Application />
|
|
32
33
|
</BrowserRouter>
|
package/src/index.ts
CHANGED
|
@@ -8,7 +8,7 @@ const validThemeKeys = ['checkbox', 'container', 'label'] as const;
|
|
|
8
8
|
|
|
9
9
|
type PropT = {
|
|
10
10
|
checked?: boolean;
|
|
11
|
-
label?:
|
|
11
|
+
label?: React.ReactNode;
|
|
12
12
|
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
13
13
|
theme: Theme<typeof validThemeKeys>;
|
|
14
14
|
};
|
|
@@ -20,7 +20,7 @@ const Checkbox: React.FunctionComponent<PropT> = ({
|
|
|
20
20
|
theme,
|
|
21
21
|
}) => (
|
|
22
22
|
<div className={theme.container}>
|
|
23
|
-
{ label === undefined ? null : <
|
|
23
|
+
{ label === undefined ? null : <div className={theme.label}>{label}</div> }
|
|
24
24
|
<input
|
|
25
25
|
checked={checked}
|
|
26
26
|
className={theme.checkbox}
|
|
@@ -56,7 +56,7 @@ const ThemedCheckbox = themed(
|
|
|
56
56
|
*/
|
|
57
57
|
Checkbox.propTypes = {
|
|
58
58
|
checked: PT.bool,
|
|
59
|
-
label: PT.
|
|
59
|
+
label: PT.node,
|
|
60
60
|
onChange: PT.func,
|
|
61
61
|
theme: ThemedCheckbox.themeType.isRequired,
|
|
62
62
|
};
|
|
@@ -12,7 +12,7 @@ const validThemeKeys = [
|
|
|
12
12
|
] as const;
|
|
13
13
|
|
|
14
14
|
type PropsT = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
15
|
-
label?:
|
|
15
|
+
label?: React.ReactNode;
|
|
16
16
|
theme: Theme<typeof validThemeKeys>;
|
|
17
17
|
};
|
|
18
18
|
|
|
@@ -34,7 +34,7 @@ const Input = forwardRef<HTMLInputElement, PropsT>((
|
|
|
34
34
|
ref,
|
|
35
35
|
) => (
|
|
36
36
|
<span className={theme.container}>
|
|
37
|
-
{ label === undefined ? null : <
|
|
37
|
+
{ label === undefined ? null : <div className={theme.label}>{label}</div> }
|
|
38
38
|
<input
|
|
39
39
|
className={theme.input}
|
|
40
40
|
ref={ref}
|
|
@@ -46,7 +46,7 @@ const Input = forwardRef<HTMLInputElement, PropsT>((
|
|
|
46
46
|
const ThemedInput = themed(Input, 'Input', validThemeKeys, defaultTheme);
|
|
47
47
|
|
|
48
48
|
Input.propTypes = {
|
|
49
|
-
label: PT.
|
|
49
|
+
label: PT.node,
|
|
50
50
|
theme: ThemedInput.themeType.isRequired,
|
|
51
51
|
};
|
|
52
52
|
|
|
@@ -15,12 +15,14 @@ import PT from 'prop-types';
|
|
|
15
15
|
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
16
16
|
|
|
17
17
|
import baseTheme from './base-theme.scss';
|
|
18
|
-
import './styles.scss';
|
|
18
|
+
import S from './styles.scss';
|
|
19
19
|
|
|
20
20
|
const validThemeKeys = ['container', 'overlay'] as const;
|
|
21
21
|
|
|
22
22
|
type PropsT = {
|
|
23
23
|
children?: ReactNode;
|
|
24
|
+
containerStyle?: React.CSSProperties;
|
|
25
|
+
dontDisableScrolling?: boolean;
|
|
24
26
|
onCancel?: () => void;
|
|
25
27
|
theme: Theme<typeof validThemeKeys>;
|
|
26
28
|
};
|
|
@@ -38,6 +40,8 @@ type PropsT = {
|
|
|
38
40
|
*/
|
|
39
41
|
const BaseModal: React.FunctionComponent<PropsT> = ({
|
|
40
42
|
children,
|
|
43
|
+
containerStyle,
|
|
44
|
+
dontDisableScrolling,
|
|
41
45
|
onCancel,
|
|
42
46
|
theme,
|
|
43
47
|
}) => {
|
|
@@ -47,15 +51,25 @@ const BaseModal: React.FunctionComponent<PropsT> = ({
|
|
|
47
51
|
|
|
48
52
|
useEffect(() => {
|
|
49
53
|
const p = document.createElement('div');
|
|
50
|
-
document.body.classList.add('scrolling-disabled-by-modal');
|
|
51
54
|
document.body.appendChild(p);
|
|
52
55
|
setPortal(p);
|
|
53
56
|
return () => {
|
|
54
|
-
document.body.classList.remove('scrolling-disabled-by-modal');
|
|
55
57
|
document.body.removeChild(p);
|
|
56
58
|
};
|
|
57
59
|
}, []);
|
|
58
60
|
|
|
61
|
+
// Disables window scrolling, if it is not opted-out.
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!dontDisableScrolling) {
|
|
64
|
+
document.body.classList.add(S.scrollingDisabledByModal);
|
|
65
|
+
}
|
|
66
|
+
return () => {
|
|
67
|
+
if (!dontDisableScrolling) {
|
|
68
|
+
document.body.classList.remove(S.scrollingDisabledByModal);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}, [dontDisableScrolling]);
|
|
72
|
+
|
|
59
73
|
const focusLast = useMemo(() => (
|
|
60
74
|
<div
|
|
61
75
|
onFocus={() => {
|
|
@@ -98,6 +112,7 @@ const BaseModal: React.FunctionComponent<PropsT> = ({
|
|
|
98
112
|
onWheel={(event) => event.stopPropagation()}
|
|
99
113
|
ref={containerRef}
|
|
100
114
|
role="dialog"
|
|
115
|
+
style={containerStyle}
|
|
101
116
|
>
|
|
102
117
|
{children}
|
|
103
118
|
</div>
|
|
@@ -124,14 +139,18 @@ const ThemedModal = themed(
|
|
|
124
139
|
);
|
|
125
140
|
|
|
126
141
|
BaseModal.propTypes = {
|
|
127
|
-
onCancel: PT.func,
|
|
128
142
|
children: PT.node,
|
|
143
|
+
containerStyle: PT.shape({}),
|
|
144
|
+
dontDisableScrolling: PT.bool,
|
|
145
|
+
onCancel: PT.func,
|
|
129
146
|
theme: ThemedModal.themeType.isRequired,
|
|
130
147
|
};
|
|
131
148
|
|
|
132
149
|
BaseModal.defaultProps = {
|
|
133
|
-
onCancel: noop,
|
|
134
150
|
children: null,
|
|
151
|
+
containerStyle: undefined,
|
|
152
|
+
dontDisableScrolling: false,
|
|
153
|
+
onCancel: noop,
|
|
135
154
|
};
|
|
136
155
|
|
|
137
156
|
export default ThemedModal;
|
|
@@ -12,6 +12,7 @@ const validThemeKeys = [
|
|
|
12
12
|
] as const;
|
|
13
13
|
|
|
14
14
|
type Props = {
|
|
15
|
+
disabled?: boolean;
|
|
15
16
|
onChange?: React.ChangeEventHandler<HTMLTextAreaElement>;
|
|
16
17
|
onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>;
|
|
17
18
|
placeholder?: string;
|
|
@@ -20,6 +21,7 @@ type Props = {
|
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
const TextArea: React.FunctionComponent<Props> = ({
|
|
24
|
+
disabled,
|
|
23
25
|
onChange,
|
|
24
26
|
onKeyDown,
|
|
25
27
|
placeholder,
|
|
@@ -66,6 +68,7 @@ const TextArea: React.FunctionComponent<Props> = ({
|
|
|
66
68
|
value={localValue}
|
|
67
69
|
/>
|
|
68
70
|
<textarea
|
|
71
|
+
disabled={disabled}
|
|
69
72
|
// When value is "undefined" the text area is not-managed, and we should
|
|
70
73
|
// manage it internally for the measurement / resizing functionality
|
|
71
74
|
// to work.
|
|
@@ -90,6 +93,7 @@ const ThemedTextArea = themed(
|
|
|
90
93
|
);
|
|
91
94
|
|
|
92
95
|
TextArea.propTypes = {
|
|
96
|
+
disabled: PT.bool,
|
|
93
97
|
onChange: PT.func,
|
|
94
98
|
onKeyDown: PT.func,
|
|
95
99
|
placeholder: PT.string,
|
|
@@ -98,6 +102,7 @@ TextArea.propTypes = {
|
|
|
98
102
|
};
|
|
99
103
|
|
|
100
104
|
TextArea.defaultProps = {
|
|
105
|
+
disabled: false,
|
|
101
106
|
onChange: undefined,
|
|
102
107
|
onKeyDown: undefined,
|
|
103
108
|
placeholder: '',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
@use "sass:color";
|
|
1
2
|
@import "styles/mixins";
|
|
2
3
|
|
|
3
4
|
*,
|
|
@@ -28,6 +29,13 @@
|
|
|
28
29
|
&::placeholder {
|
|
29
30
|
color: gray;
|
|
30
31
|
}
|
|
32
|
+
|
|
33
|
+
&:disabled {
|
|
34
|
+
border-color: color.adjust($color: gray, $alpha: -0.66);
|
|
35
|
+
cursor: not-allowed;
|
|
36
|
+
color: color.adjust($color: gray, $alpha: -0.66);
|
|
37
|
+
user-select: none;
|
|
38
|
+
}
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
&.hidden {
|
|
@@ -3,7 +3,6 @@ import qs from 'qs';
|
|
|
3
3
|
|
|
4
4
|
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
5
5
|
|
|
6
|
-
import ScalableRect from 'components/ScalableRect';
|
|
7
6
|
import Throbber from 'components/Throbber';
|
|
8
7
|
|
|
9
8
|
import baseTheme from './base.scss';
|
|
@@ -57,7 +56,7 @@ const YouTubeVideo: React.FunctionComponent<PropsT> = ({
|
|
|
57
56
|
// More query parameters can be exposed via the component props.
|
|
58
57
|
|
|
59
58
|
return (
|
|
60
|
-
<
|
|
59
|
+
<div className={theme.container}>
|
|
61
60
|
<Throbber theme={throbberTheme} />
|
|
62
61
|
<iframe
|
|
63
62
|
allow="autoplay"
|
|
@@ -66,7 +65,7 @@ const YouTubeVideo: React.FunctionComponent<PropsT> = ({
|
|
|
66
65
|
src={url}
|
|
67
66
|
title={title}
|
|
68
67
|
/>
|
|
69
|
-
</
|
|
68
|
+
</div>
|
|
70
69
|
);
|
|
71
70
|
};
|
|
72
71
|
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
* Just an aggregation of all exported components into a single module.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
export * from 'components/selectors';
|
|
6
|
+
|
|
5
7
|
export { default as Button } from 'components/Button';
|
|
6
8
|
export { default as Checkbox } from 'components/Checkbox';
|
|
7
|
-
export { default as Dropdown } from 'components/Dropdown';
|
|
8
9
|
export { default as Input } from 'components/Input';
|
|
9
10
|
export { default as Link } from 'components/Link';
|
|
10
11
|
export { default as PageLayout } from 'components/PageLayout';
|
|
11
12
|
export { default as MetaTags } from 'components/MetaTags';
|
|
12
13
|
export { default as Modal, BaseModal } from 'components/Modal';
|
|
13
14
|
export { default as NavLink } from 'components/NavLink';
|
|
14
|
-
export { default as ScalableRect } from 'components/ScalableRect';
|
|
15
15
|
export { default as Throbber } from 'components/Throbber';
|
|
16
16
|
export { default as WithTooltip } from 'components/WithTooltip';
|
|
17
17
|
export { default as YouTubeVideo } from 'components/YouTubeVideo';
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import PT from 'prop-types';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
import { BaseModal } from 'components/Modal';
|
|
5
|
+
|
|
6
|
+
import S from './style.scss';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
type OptionT,
|
|
10
|
+
type OptionsT,
|
|
11
|
+
optionsValidator,
|
|
12
|
+
optionValueName,
|
|
13
|
+
} from '../../common';
|
|
14
|
+
|
|
15
|
+
type PropsT = {
|
|
16
|
+
anchorRect: {
|
|
17
|
+
bottom: number;
|
|
18
|
+
left: number;
|
|
19
|
+
width: number;
|
|
20
|
+
};
|
|
21
|
+
containerClass: string;
|
|
22
|
+
filter?: (item: OptionT<React.ReactNode> | string) => boolean;
|
|
23
|
+
optionClass: string;
|
|
24
|
+
options: OptionsT<React.ReactNode>;
|
|
25
|
+
onCancel: () => void;
|
|
26
|
+
onChange: (value: string) => void;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const Options: React.FunctionComponent<PropsT> = ({
|
|
30
|
+
anchorRect,
|
|
31
|
+
containerClass,
|
|
32
|
+
filter,
|
|
33
|
+
onCancel,
|
|
34
|
+
onChange,
|
|
35
|
+
optionClass,
|
|
36
|
+
options,
|
|
37
|
+
}) => {
|
|
38
|
+
// Closes the dropdown (cancels the selection) on any page scrolling attempt.
|
|
39
|
+
// This is the same native <select> elements do on scrolling, and at least for
|
|
40
|
+
// now we have no reason to deal with complications needed to support open
|
|
41
|
+
// dropdowns during the scrolling (that would need to re-position it in
|
|
42
|
+
// response to the position changes of the root dropdown element).
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const listener = () => {
|
|
45
|
+
onCancel();
|
|
46
|
+
};
|
|
47
|
+
window.addEventListener('scroll', listener);
|
|
48
|
+
return () => {
|
|
49
|
+
window.removeEventListener('scroll', listener);
|
|
50
|
+
};
|
|
51
|
+
}, [onCancel]);
|
|
52
|
+
|
|
53
|
+
const optionNodes: React.ReactNode[] = [];
|
|
54
|
+
for (let i = 0; i < options.length; ++i) {
|
|
55
|
+
const option = options[i];
|
|
56
|
+
if (!filter || filter(option)) {
|
|
57
|
+
const [iValue, iName] = optionValueName(option);
|
|
58
|
+
optionNodes.push(
|
|
59
|
+
<div
|
|
60
|
+
className={optionClass}
|
|
61
|
+
onClick={() => onChange(iValue)}
|
|
62
|
+
onKeyDown={(e) => {
|
|
63
|
+
if (e.key === 'Enter') {
|
|
64
|
+
onChange(iValue);
|
|
65
|
+
}
|
|
66
|
+
}}
|
|
67
|
+
key={iValue}
|
|
68
|
+
role="button"
|
|
69
|
+
tabIndex={0}
|
|
70
|
+
>
|
|
71
|
+
{iName}
|
|
72
|
+
</div>,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<BaseModal
|
|
79
|
+
containerStyle={{
|
|
80
|
+
left: anchorRect.left,
|
|
81
|
+
top: anchorRect.bottom,
|
|
82
|
+
width: anchorRect.width,
|
|
83
|
+
}}
|
|
84
|
+
dontDisableScrolling
|
|
85
|
+
onCancel={onCancel}
|
|
86
|
+
theme={{
|
|
87
|
+
ad: '',
|
|
88
|
+
hoc: '',
|
|
89
|
+
container: containerClass,
|
|
90
|
+
context: '',
|
|
91
|
+
overlay: S.overlay,
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
{optionNodes}
|
|
95
|
+
</BaseModal>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
Options.propTypes = {
|
|
100
|
+
anchorRect: PT.shape({
|
|
101
|
+
bottom: PT.number.isRequired,
|
|
102
|
+
left: PT.number.isRequired,
|
|
103
|
+
width: PT.number.isRequired,
|
|
104
|
+
}).isRequired,
|
|
105
|
+
containerClass: PT.string.isRequired,
|
|
106
|
+
filter: PT.func,
|
|
107
|
+
onCancel: PT.func.isRequired,
|
|
108
|
+
onChange: PT.func.isRequired,
|
|
109
|
+
optionClass: PT.string.isRequired,
|
|
110
|
+
options: optionsValidator.isRequired,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
Options.defaultProps = {
|
|
114
|
+
filter: undefined,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export default Options;
|