@dr.pogodin/react-utils 1.25.5 → 1.26.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/babel.config.js +3 -1
- package/bin/build.js +25 -5
- package/build/development/client/getInj.js +9 -8
- package/build/development/client/getInj.js.map +1 -1
- package/build/development/client/index.js +6 -3
- package/build/development/client/index.js.map +1 -1
- package/build/development/client/init.js +4 -0
- package/build/development/client/init.js.map +1 -1
- package/build/development/index.js +168 -42
- package/build/development/index.js.map +1 -1
- package/build/development/server/Cache.js +13 -13
- package/build/development/server/Cache.js.map +1 -1
- package/build/development/server/index.js +16 -24
- package/build/development/server/index.js.map +1 -1
- package/build/development/server/renderer.js +56 -44
- package/build/development/server/renderer.js.map +1 -1
- package/build/development/server/server.js +9 -5
- package/build/development/server/server.js.map +1 -1
- package/build/development/server/utils/errors.js +12 -9
- package/build/development/server/utils/errors.js.map +1 -1
- package/build/development/server/utils/index.js +2 -2
- package/build/development/server/utils/index.js.map +1 -1
- package/build/development/shared/components/Button/index.js +8 -7
- package/build/development/shared/components/Button/index.js.map +1 -1
- package/build/development/shared/components/Checkbox/index.js +25 -28
- package/build/development/shared/components/Checkbox/index.js.map +1 -1
- package/build/development/shared/components/Dropdown/index.js +25 -19
- package/build/development/shared/components/Dropdown/index.js.map +1 -1
- package/build/development/shared/components/GenericLink/index.js +44 -37
- package/build/development/shared/components/GenericLink/index.js.map +1 -1
- package/build/development/shared/components/Input/index.js +8 -9
- package/build/development/shared/components/Input/index.js.map +1 -1
- package/build/development/shared/components/Link.js +10 -9
- package/build/development/shared/components/Link.js.map +1 -1
- package/build/development/shared/components/MetaTags.js +22 -18
- package/build/development/shared/components/MetaTags.js.map +1 -1
- package/build/development/shared/components/Modal/index.js +17 -18
- package/build/development/shared/components/Modal/index.js.map +1 -1
- package/build/development/shared/components/NavLink.js +10 -9
- package/build/development/shared/components/NavLink.js.map +1 -1
- package/build/development/shared/components/PageLayout/index.js +17 -20
- package/build/development/shared/components/PageLayout/index.js.map +1 -1
- package/build/development/shared/components/ScalableRect/index.js +27 -7
- package/build/development/shared/components/ScalableRect/index.js.map +1 -1
- package/build/development/shared/components/Throbber/index.js +14 -23
- package/build/development/shared/components/Throbber/index.js.map +1 -1
- package/build/development/shared/components/WithTooltip/Tooltip.js +20 -24
- package/build/development/shared/components/WithTooltip/Tooltip.js.map +1 -1
- package/build/development/shared/components/WithTooltip/index.js +11 -11
- package/build/development/shared/components/WithTooltip/index.js.map +1 -1
- package/build/development/shared/components/YouTubeVideo/index.js +16 -15
- package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/development/shared/components/index.js +2 -2
- package/build/development/shared/components/index.js.map +1 -1
- package/build/development/shared/utils/config.js +1 -2
- package/build/development/shared/utils/config.js.map +1 -1
- package/build/development/shared/utils/globalState.js +15 -0
- package/build/development/shared/utils/globalState.js.map +1 -0
- package/build/development/shared/utils/index.js +13 -11
- package/build/development/shared/utils/index.js.map +1 -1
- package/build/development/shared/utils/isomorphy/buildInfo.js +7 -3
- package/build/development/shared/utils/isomorphy/buildInfo.js.map +1 -1
- package/build/development/shared/utils/isomorphy/environment-check.js +2 -4
- package/build/development/shared/utils/isomorphy/environment-check.js.map +1 -1
- package/build/development/shared/utils/isomorphy/index.js.map +1 -1
- package/build/development/shared/utils/jest/E2eSsrEnv.js +35 -28
- package/build/development/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/development/shared/utils/jest/global.js +17 -0
- package/build/development/shared/utils/jest/global.js.map +1 -0
- package/build/development/shared/utils/jest/index.js +18 -11
- package/build/development/shared/utils/jest/index.js.map +1 -1
- package/build/development/shared/utils/splitComponent.js +25 -34
- package/build/development/shared/utils/splitComponent.js.map +1 -1
- package/build/development/shared/utils/time.js +16 -13
- package/build/development/shared/utils/time.js.map +1 -1
- package/build/development/shared/utils/webpack.js +3 -3
- package/build/development/shared/utils/webpack.js.map +1 -1
- package/build/development/web.bundle.js +92 -82
- package/build/production/client/getInj.js +1 -1
- package/build/production/client/getInj.js.map +1 -1
- package/build/production/client/index.js +4 -4
- package/build/production/client/index.js.map +1 -1
- package/build/production/client/init.js +3 -1
- package/build/production/client/init.js.map +1 -1
- package/build/production/index.js +1 -1
- package/build/production/index.js.map +1 -1
- package/build/production/server/Cache.js +7 -8
- package/build/production/server/Cache.js.map +1 -1
- package/build/production/server/index.js +5 -4
- package/build/production/server/index.js.map +1 -1
- package/build/production/server/renderer.js +32 -30
- package/build/production/server/renderer.js.map +1 -1
- package/build/production/server/server.js +7 -5
- package/build/production/server/server.js.map +1 -1
- package/build/production/server/utils/errors.js +9 -10
- package/build/production/server/utils/errors.js.map +1 -1
- package/build/production/server/utils/index.js +1 -1
- package/build/production/server/utils/index.js.map +1 -1
- package/build/production/shared/components/Button/index.js +4 -4
- package/build/production/shared/components/Button/index.js.map +1 -1
- package/build/production/shared/components/Checkbox/index.js +12 -12
- package/build/production/shared/components/Checkbox/index.js.map +1 -1
- package/build/production/shared/components/Dropdown/index.js +11 -11
- package/build/production/shared/components/Dropdown/index.js.map +1 -1
- package/build/production/shared/components/GenericLink/index.js +25 -20
- package/build/production/shared/components/GenericLink/index.js.map +1 -1
- package/build/production/shared/components/Input/index.js +7 -7
- package/build/production/shared/components/Input/index.js.map +1 -1
- package/build/production/shared/components/Link.js +2 -2
- package/build/production/shared/components/Link.js.map +1 -1
- package/build/production/shared/components/MetaTags.js +10 -10
- 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/NavLink.js +1 -1
- package/build/production/shared/components/NavLink.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/ScalableRect/index.js +7 -3
- package/build/production/shared/components/ScalableRect/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 +13 -13
- package/build/production/shared/components/WithTooltip/Tooltip.js.map +1 -1
- package/build/production/shared/components/WithTooltip/index.js +3 -3
- package/build/production/shared/components/WithTooltip/index.js.map +1 -1
- package/build/production/shared/components/YouTubeVideo/index.js +7 -7
- 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/utils/config.js +1 -1
- package/build/production/shared/utils/config.js.map +1 -1
- package/build/production/shared/utils/globalState.js +3 -0
- package/build/production/shared/utils/globalState.js.map +1 -0
- package/build/production/shared/utils/index.js +3 -3
- package/build/production/shared/utils/index.js.map +1 -1
- package/build/production/shared/utils/isomorphy/buildInfo.js +7 -4
- package/build/production/shared/utils/isomorphy/buildInfo.js.map +1 -1
- package/build/production/shared/utils/isomorphy/environment-check.js +2 -2
- package/build/production/shared/utils/isomorphy/environment-check.js.map +1 -1
- package/build/production/shared/utils/isomorphy/index.js.map +1 -1
- package/build/production/shared/utils/jest/E2eSsrEnv.js +9 -9
- package/build/production/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/production/shared/utils/jest/global.js +2 -0
- package/build/production/shared/utils/jest/global.js.map +1 -0
- package/build/production/shared/utils/jest/index.js +6 -6
- package/build/production/shared/utils/jest/index.js.map +1 -1
- package/build/production/shared/utils/splitComponent.js +16 -16
- package/build/production/shared/utils/splitComponent.js.map +1 -1
- package/build/production/shared/utils/time.js +12 -8
- package/build/production/shared/utils/time.js.map +1 -1
- package/build/production/shared/utils/webpack.js +3 -3
- package/build/production/shared/utils/webpack.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/client/getInj.d.ts +3 -0
- package/build/types-code/client/index.d.ts +11 -0
- package/build/types-code/client/init.d.ts +9 -0
- package/build/types-code/index.d.ts +10 -0
- package/build/types-code/server/Cache.d.ts +37 -0
- package/build/types-code/server/index.d.ts +145 -0
- package/build/types-code/server/renderer.d.ts +106 -0
- package/build/types-code/server/server.d.ts +41 -0
- package/build/types-code/server/utils/errors.d.ts +104 -0
- package/build/types-code/server/utils/index.d.ts +1 -0
- package/build/types-code/shared/components/Button/index.d.ts +27 -0
- package/build/types-code/shared/components/Checkbox/index.d.ts +21 -0
- package/build/types-code/shared/components/Dropdown/index.d.ts +23 -0
- package/build/types-code/shared/components/GenericLink/index.d.ts +61 -0
- package/build/types-code/shared/components/Input/index.d.ts +11 -0
- package/build/types-code/shared/components/Link.d.ts +12 -0
- package/build/types-code/shared/components/MetaTags.d.ts +68 -0
- package/build/types-code/shared/components/Modal/index.d.ts +26 -0
- package/build/types-code/shared/components/NavLink.d.ts +5 -0
- package/build/types-code/shared/components/PageLayout/index.d.ts +16 -0
- package/build/types-code/shared/components/ScalableRect/index.d.ts +19 -0
- package/build/types-code/shared/components/Throbber/index.d.ts +9 -0
- package/build/types-code/shared/components/WithTooltip/Tooltip.d.ts +23 -0
- package/build/types-code/shared/components/WithTooltip/index.d.ts +17 -0
- package/build/types-code/shared/components/YouTubeVideo/index.d.ts +13 -0
- package/build/types-code/shared/components/index.d.ts +16 -0
- package/build/types-code/shared/utils/config.d.ts +2 -0
- package/build/types-code/shared/utils/globalState.d.ts +20 -0
- package/build/types-code/shared/utils/index.d.ts +52 -0
- package/build/types-code/shared/utils/isomorphy/buildInfo.d.ts +23 -0
- package/build/types-code/shared/utils/isomorphy/environment-check.d.ts +11 -0
- package/build/types-code/shared/utils/isomorphy/index.d.ts +20 -0
- package/build/types-code/shared/utils/jest/E2eSsrEnv.d.ts +31 -0
- package/build/types-code/shared/utils/jest/global.d.ts +12 -0
- package/build/types-code/shared/utils/jest/index.d.ts +85 -0
- package/build/types-code/shared/utils/splitComponent.d.ts +41 -0
- package/build/types-code/shared/utils/time.d.ts +62 -0
- package/build/types-code/shared/utils/webpack.d.ts +18 -0
- package/build/types-scss/__tests__/js/config/publicPath support/__assets__/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/js/config/stylename-generation/__assets__/MockPackageA/TestComponent/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/js/config/stylename-generation/__assets__/MockPackageB/TestComponent/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/js/config/stylename-generation/__assets__/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/js/shared/components/NavLink/styles.scss.d.ts +1 -0
- package/build/types-scss/__tests__/js/shared/utils/splitComponent/__assets__/SampleScene/ComponentA/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/js/shared/utils/splitComponent/__assets__/SampleScene/ComponentB/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/js/shared/utils/splitComponent/__assets__/SampleScene/ComponentC/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/js/shared/utils/splitComponent/__assets__/SampleScene/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/config/publicPath support/__assets__/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/config/stylename-generation/__assets__/MockPackageA/TestComponent/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/config/stylename-generation/__assets__/MockPackageB/TestComponent/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/config/stylename-generation/__assets__/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/shared/components/NavLink/styles.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/shared/utils/splitComponent/__assets__/SampleScene/ComponentA/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/shared/utils/splitComponent/__assets__/SampleScene/ComponentB/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/shared/utils/splitComponent/__assets__/SampleScene/ComponentC/style.scss.d.ts +1 -0
- package/build/types-scss/__tests__/ts/shared/utils/splitComponent/__assets__/SampleScene/style.scss.d.ts +1 -0
- package/build/types-scss/src/shared/components/Button/style.scss.d.ts +6 -0
- package/build/types-scss/src/shared/components/Checkbox/theme.scss.d.ts +6 -0
- package/build/types-scss/src/shared/components/Dropdown/theme.scss.d.ts +9 -0
- package/build/types-scss/src/shared/components/GenericLink/style.scss.d.ts +1 -0
- package/build/types-scss/src/shared/components/Input/theme.scss.d.ts +6 -0
- package/build/types-scss/src/shared/components/Modal/base-theme.scss.d.ts +5 -0
- package/build/types-scss/src/shared/components/PageLayout/base-theme.scss.d.ts +6 -0
- package/build/types-scss/src/shared/components/ScalableRect/style.scss.d.ts +2 -0
- package/build/types-scss/src/shared/components/Throbber/theme.scss.d.ts +6 -0
- package/build/types-scss/src/shared/components/WithTooltip/default-theme.scss.d.ts +7 -0
- package/build/types-scss/src/shared/components/YouTubeVideo/base.scss.d.ts +5 -0
- package/build/types-scss/src/shared/components/YouTubeVideo/throbber.scss.d.ts +4 -0
- package/config/eslint/jest.json +3 -2
- package/config/eslint/typescript.js +34 -0
- package/config/jest/default.js +3 -3
- package/package.json +75 -33
- package/src/client/getInj.ts +43 -0
- package/src/client/index.tsx +40 -0
- package/src/client/init.ts +47 -0
- package/src/index.ts +58 -0
- package/src/server/Cache.ts +68 -0
- package/src/server/index.ts +230 -0
- package/src/server/renderer.tsx +604 -0
- package/src/server/server.ts +309 -0
- package/src/server/utils/errors.ts +135 -0
- package/src/server/utils/index.ts +3 -0
- package/src/shared/components/Button/index.tsx +146 -0
- package/src/shared/components/Button/style.scss +53 -0
- package/src/shared/components/Checkbox/index.tsx +71 -0
- package/src/shared/components/Checkbox/theme.scss +43 -0
- package/src/shared/components/Dropdown/index.tsx +144 -0
- package/src/shared/components/Dropdown/theme.scss +63 -0
- package/src/shared/components/GenericLink/index.tsx +157 -0
- package/src/shared/components/GenericLink/style.scss +3 -0
- package/src/shared/components/Input/index.tsx +59 -0
- package/src/shared/components/Input/theme.scss +27 -0
- package/src/shared/components/Link.tsx +21 -0
- package/src/shared/components/MetaTags.tsx +170 -0
- package/src/shared/components/Modal/base-theme.scss +38 -0
- package/src/shared/components/Modal/index.tsx +144 -0
- package/src/shared/components/Modal/styles.scss +5 -0
- package/src/shared/components/NavLink.tsx +13 -0
- package/src/shared/components/PageLayout/base-theme.scss +30 -0
- package/src/shared/components/PageLayout/index.tsx +76 -0
- package/src/shared/components/ScalableRect/index.tsx +84 -0
- package/src/shared/components/ScalableRect/style.scss +10 -0
- package/src/shared/components/Throbber/index.tsx +43 -0
- package/src/shared/components/Throbber/theme.scss +26 -0
- package/src/shared/components/WithTooltip/Tooltip.tsx +353 -0
- package/src/shared/components/WithTooltip/default-theme.scss +36 -0
- package/src/shared/components/WithTooltip/index.tsx +204 -0
- package/src/shared/components/YouTubeVideo/base.scss +13 -0
- package/src/shared/components/YouTubeVideo/index.tsx +96 -0
- package/src/shared/components/YouTubeVideo/throbber.scss +11 -0
- package/src/shared/components/index.ts +17 -0
- package/src/shared/utils/config.ts +21 -0
- package/src/shared/utils/globalState.ts +29 -0
- package/src/shared/utils/index.ts +105 -0
- package/src/shared/utils/isomorphy/buildInfo.ts +54 -0
- package/src/shared/utils/isomorphy/environment-check.ts +18 -0
- package/src/shared/utils/isomorphy/index.ts +38 -0
- package/src/shared/utils/jest/E2eSsrEnv.ts +250 -0
- package/src/shared/utils/jest/global.ts +19 -0
- package/src/shared/utils/jest/index.tsx +157 -0
- package/src/shared/utils/splitComponent.tsx +255 -0
- package/src/shared/utils/time.ts +118 -0
- package/src/shared/utils/webpack.ts +45 -0
- package/src/styles/_global/reset.css +52 -0
- package/src/styles/global.scss +11 -0
- package/tsconfig.configs.json +18 -0
- package/tsconfig.json +27 -0
- package/tsconfig.types.json +53 -0
- package/typed-scss-modules.config.ts +9 -0
- package/types.d.ts +37 -0
- package/{webpack.config.js → webpack.config.ts} +7 -3
- package/config/babel/node-ssr.js +0 -85
- package/config/babel/webpack.js +0 -122
- package/config/webpack/app-base.js +0 -330
- package/config/webpack/app-development.js +0 -80
- package/config/webpack/app-production.js +0 -60
- package/config/webpack/lib-base.js +0 -155
- package/config/webpack/lib-development.js +0 -45
- package/config/webpack/lib-production.js +0 -44
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import PT from 'prop-types';
|
|
2
|
+
|
|
3
|
+
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
4
|
+
|
|
5
|
+
import defaultTheme from './theme.scss';
|
|
6
|
+
|
|
7
|
+
type PropT = {
|
|
8
|
+
checked?: boolean;
|
|
9
|
+
label?: string;
|
|
10
|
+
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
11
|
+
theme: Theme & {
|
|
12
|
+
checkbox?: string;
|
|
13
|
+
container?: string
|
|
14
|
+
label?: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const Checkbox: React.FunctionComponent<PropT> = ({
|
|
19
|
+
checked,
|
|
20
|
+
label,
|
|
21
|
+
onChange,
|
|
22
|
+
theme,
|
|
23
|
+
}) => (
|
|
24
|
+
<div className={theme.container}>
|
|
25
|
+
{ label === undefined ? null : <p className={theme.label}>{label}</p> }
|
|
26
|
+
<input
|
|
27
|
+
checked={checked}
|
|
28
|
+
className={theme.checkbox}
|
|
29
|
+
onChange={onChange}
|
|
30
|
+
type="checkbox"
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Checkbox component theme: a map of
|
|
37
|
+
* CSS classes to append to its elements:
|
|
38
|
+
* @prop [checkbox] to the underlying checkbox `<input>` element.
|
|
39
|
+
* @prop [container] to the root checkbox element.
|
|
40
|
+
* @prop [label] to the checkbox label element.
|
|
41
|
+
*/
|
|
42
|
+
const ThemedCheckbox = themed(Checkbox, 'Checkbox', [
|
|
43
|
+
'checkbox',
|
|
44
|
+
'container',
|
|
45
|
+
'label',
|
|
46
|
+
], defaultTheme);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The `<Checkbox>` component implements themeable checkboxes.
|
|
50
|
+
* @param [props] Component properties.
|
|
51
|
+
* @param [props.checked] Checkbox value.
|
|
52
|
+
* @param [props.label] Checkbox label.
|
|
53
|
+
* @param [props.onChange] State change handler.
|
|
54
|
+
* @param [props.theme] _Ad hoc_ theme.
|
|
55
|
+
* @param [props....]
|
|
56
|
+
* [Other properties of themeable components](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties).
|
|
57
|
+
*/
|
|
58
|
+
Checkbox.propTypes = {
|
|
59
|
+
checked: PT.bool,
|
|
60
|
+
label: PT.string,
|
|
61
|
+
onChange: PT.func,
|
|
62
|
+
theme: ThemedCheckbox.themeType.isRequired,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
Checkbox.defaultProps = {
|
|
66
|
+
checked: undefined,
|
|
67
|
+
label: undefined,
|
|
68
|
+
onChange: undefined,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default ThemedCheckbox;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
*,
|
|
2
|
+
.context,
|
|
3
|
+
.ad.hoc {
|
|
4
|
+
&.checkbox {
|
|
5
|
+
appearance: none;
|
|
6
|
+
background: white;
|
|
7
|
+
border: 1px solid gray;
|
|
8
|
+
border-radius: 0.3em;
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
font: inherit;
|
|
11
|
+
height: 1.5em;
|
|
12
|
+
outline: none;
|
|
13
|
+
margin: 0;
|
|
14
|
+
width: 1.5em;
|
|
15
|
+
|
|
16
|
+
&:checked {
|
|
17
|
+
&::after {
|
|
18
|
+
background: black;
|
|
19
|
+
border-radius: 0.3em;
|
|
20
|
+
content: "";
|
|
21
|
+
display: block;
|
|
22
|
+
height: 1em;
|
|
23
|
+
margin: 0.2em;
|
|
24
|
+
width: 1em;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&:focus {
|
|
29
|
+
border-color: blue;
|
|
30
|
+
box-shadow: 0 0 3px 1px lightblue;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&.container {
|
|
35
|
+
align-items: center;
|
|
36
|
+
display: inline-flex;
|
|
37
|
+
margin: 0.1em;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&.label {
|
|
41
|
+
margin: 0 0.6em 0 1.5em;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import PT from 'prop-types';
|
|
2
|
+
|
|
3
|
+
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
4
|
+
|
|
5
|
+
import defaultTheme from './theme.scss';
|
|
6
|
+
|
|
7
|
+
type DropdownOptionT = {
|
|
8
|
+
name?: string | null;
|
|
9
|
+
value: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type PropsT = {
|
|
13
|
+
filter?: (item: DropdownOptionT | string) => boolean;
|
|
14
|
+
label?: string;
|
|
15
|
+
onChange?: React.ChangeEventHandler<HTMLSelectElement>;
|
|
16
|
+
options?: Array<DropdownOptionT | string>;
|
|
17
|
+
theme: Theme & {
|
|
18
|
+
arrow?: string;
|
|
19
|
+
container?: string;
|
|
20
|
+
hiddenOption?: string;
|
|
21
|
+
label?: string;
|
|
22
|
+
option?: string;
|
|
23
|
+
select?: string;
|
|
24
|
+
};
|
|
25
|
+
value?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Implements a themeable dropdown list. Internally it is rendered with help of
|
|
30
|
+
* the standard HTML `<select>` element, thus the styling support is somewhat
|
|
31
|
+
* limited.
|
|
32
|
+
* @param [props] Component properties.
|
|
33
|
+
* @param [props.filter] Options filter function. If provided, only
|
|
34
|
+
* those elements of `options` list will be used by the dropdown, for which this
|
|
35
|
+
* filter returns `true`.
|
|
36
|
+
* @param [props.label] Dropdown label.
|
|
37
|
+
* @param [props.onChange] Selection event handler.
|
|
38
|
+
* @param [props.options=[]] Array of dropdown
|
|
39
|
+
* options. For string elements the option value and name will be the same.
|
|
40
|
+
* It is allowed to mix DropdownOption and string elements in the same option
|
|
41
|
+
* list.
|
|
42
|
+
* @param [props.theme] _Ad hoc_ theme.
|
|
43
|
+
* @param [props.value] Currently selected value.
|
|
44
|
+
* @param [props....]
|
|
45
|
+
* [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)
|
|
46
|
+
*/
|
|
47
|
+
const Dropdown: React.FunctionComponent<PropsT> = ({
|
|
48
|
+
filter,
|
|
49
|
+
label,
|
|
50
|
+
onChange,
|
|
51
|
+
options = [],
|
|
52
|
+
theme,
|
|
53
|
+
value,
|
|
54
|
+
}) => {
|
|
55
|
+
let isValidValue = false;
|
|
56
|
+
const optionElements = [];
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < options.length; ++i) {
|
|
59
|
+
const option = options[i];
|
|
60
|
+
if (!filter || filter(option)) {
|
|
61
|
+
let optionValue: string;
|
|
62
|
+
let optionName: string;
|
|
63
|
+
if (typeof option === 'string') {
|
|
64
|
+
optionName = option;
|
|
65
|
+
optionValue = option;
|
|
66
|
+
} else {
|
|
67
|
+
optionName = option.name || option.value;
|
|
68
|
+
optionValue = option.value;
|
|
69
|
+
}
|
|
70
|
+
isValidValue ||= optionValue === value;
|
|
71
|
+
optionElements.push(
|
|
72
|
+
<option className={theme.option} key={optionValue} value={optionValue}>
|
|
73
|
+
{optionName}
|
|
74
|
+
</option>,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// NOTE: This element represents the current `value` when it does not match
|
|
80
|
+
// any valid option. In Chrome, and some other browsers, we are able to hide
|
|
81
|
+
// it from the opened dropdown; in others, e.g. Safari, the best we can do is
|
|
82
|
+
// to show it as disabled.
|
|
83
|
+
const hiddenOption = isValidValue ? null : (
|
|
84
|
+
<option
|
|
85
|
+
disabled
|
|
86
|
+
className={theme.hiddenOption}
|
|
87
|
+
key="__reactUtilsHiddenOption"
|
|
88
|
+
value={value}
|
|
89
|
+
>
|
|
90
|
+
{value}
|
|
91
|
+
</option>
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div className={theme.container}>
|
|
96
|
+
{ label === undefined ? null : <p className={theme.label}>{label}</p> }
|
|
97
|
+
<select
|
|
98
|
+
className={theme.select}
|
|
99
|
+
onChange={onChange}
|
|
100
|
+
value={value}
|
|
101
|
+
>
|
|
102
|
+
{hiddenOption}
|
|
103
|
+
{optionElements}
|
|
104
|
+
</select>
|
|
105
|
+
<div className={theme.arrow}>▼</div>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const ThemedDropdown = themed(Dropdown, 'Dropdown', [
|
|
111
|
+
'arrow',
|
|
112
|
+
'container',
|
|
113
|
+
'hiddenOption',
|
|
114
|
+
'label',
|
|
115
|
+
'option',
|
|
116
|
+
'select',
|
|
117
|
+
], defaultTheme);
|
|
118
|
+
|
|
119
|
+
Dropdown.propTypes = {
|
|
120
|
+
filter: PT.func,
|
|
121
|
+
label: PT.string,
|
|
122
|
+
onChange: PT.func,
|
|
123
|
+
options: PT.arrayOf(
|
|
124
|
+
PT.oneOfType([
|
|
125
|
+
PT.shape({
|
|
126
|
+
name: PT.string,
|
|
127
|
+
value: PT.string.isRequired,
|
|
128
|
+
}),
|
|
129
|
+
PT.string,
|
|
130
|
+
]).isRequired,
|
|
131
|
+
),
|
|
132
|
+
theme: ThemedDropdown.themeType.isRequired,
|
|
133
|
+
value: PT.string,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
Dropdown.defaultProps = {
|
|
137
|
+
filter: undefined,
|
|
138
|
+
label: undefined,
|
|
139
|
+
onChange: undefined,
|
|
140
|
+
options: [],
|
|
141
|
+
value: '',
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export default ThemedDropdown;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
@import "styles/mixins";
|
|
2
|
+
|
|
3
|
+
*,
|
|
4
|
+
.context,
|
|
5
|
+
.ad.hoc {
|
|
6
|
+
&.arrow {
|
|
7
|
+
background-image: linear-gradient(to top, lightgray, white 50%, white);
|
|
8
|
+
border: 1px solid gray;
|
|
9
|
+
border-radius: 0 0.3em 0.3em 0;
|
|
10
|
+
padding: 0.3em 0.6em;
|
|
11
|
+
pointer-events: none;
|
|
12
|
+
position: absolute;
|
|
13
|
+
right: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&.container {
|
|
17
|
+
align-items: center;
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
margin: 0.1em;
|
|
20
|
+
position: relative;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
:active + &.arrow {
|
|
24
|
+
background-image: linear-gradient(to bottom, lightgray, white 50%, white);
|
|
25
|
+
border-bottom-right-radius: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
:focus + &.arrow {
|
|
29
|
+
border-color: blue;
|
|
30
|
+
border-left-color: gray;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&.label {
|
|
34
|
+
margin: 0 0.6em 0 1.5em;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&.option { /* Empty style */ }
|
|
38
|
+
&.hiddenOption { display: none; }
|
|
39
|
+
|
|
40
|
+
&.select {
|
|
41
|
+
appearance: none;
|
|
42
|
+
background: white;
|
|
43
|
+
border: 1px solid gray;
|
|
44
|
+
border-radius: 0.3em;
|
|
45
|
+
color: inherit;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
display: inline-block;
|
|
48
|
+
font: inherit;
|
|
49
|
+
outline: none;
|
|
50
|
+
padding: 0.3em 3.3em calc(0.3em + 1px) 1.2em;
|
|
51
|
+
|
|
52
|
+
&:active {
|
|
53
|
+
background: white;
|
|
54
|
+
border-bottom-left-radius: 0;
|
|
55
|
+
border-bottom-right-radius: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&:focus {
|
|
59
|
+
border-color: blue;
|
|
60
|
+
box-shadow: 0 0 3px 1px lightblue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/* global window */
|
|
2
|
+
|
|
3
|
+
import PT from 'prop-types';
|
|
4
|
+
import { type ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
import { type Link, type NavLink } from 'react-router-dom';
|
|
7
|
+
|
|
8
|
+
import './style.scss';
|
|
9
|
+
|
|
10
|
+
type ToT = Parameters<typeof Link>[0]['to'];
|
|
11
|
+
|
|
12
|
+
interface LinkI {}
|
|
13
|
+
|
|
14
|
+
export type PropsT = {
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
className?: string;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
enforceA?: boolean;
|
|
19
|
+
keepScrollPosition?: boolean;
|
|
20
|
+
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
|
|
21
|
+
onMouseDown?: React.MouseEventHandler<HTMLAnchorElement>;
|
|
22
|
+
openNewTab?: boolean;
|
|
23
|
+
replace?: boolean;
|
|
24
|
+
routerLinkType: LinkI;
|
|
25
|
+
to?: ToT;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The `<Link>` component, and almost identical `<NavLink>` component, are
|
|
30
|
+
* auxiliary wrappers around
|
|
31
|
+
* [React Router](https://github.com/ReactTraining/react-router)'s
|
|
32
|
+
* `<Link>` and `<NavLink>` components; they help to handle external and
|
|
33
|
+
* internal links in uniform manner.
|
|
34
|
+
*
|
|
35
|
+
* @param [props] Component properties.
|
|
36
|
+
* @param [props.className] CSS classes to apply to the link.
|
|
37
|
+
* @param [props.disabled] Disables the link.
|
|
38
|
+
* @param [props.enforceA] `true` enforces rendering of the link as
|
|
39
|
+
* a simple `<a>` element.
|
|
40
|
+
* @param [props.keepScrollPosition] If `true`, and the link is
|
|
41
|
+
* rendered as a React Router's component, it won't reset the viewport scrolling
|
|
42
|
+
* position to the origin when clicked.
|
|
43
|
+
* @param [props.onClick] Event handler to trigger upon click.
|
|
44
|
+
* @param [props.onMouseDown] Event handler to trigger on MouseDown
|
|
45
|
+
* event.
|
|
46
|
+
* @param [props.openNewTab] If `true` the link opens in a new tab.
|
|
47
|
+
* @param [props.replace] When `true`, the link will replace current
|
|
48
|
+
* entry in the history stack instead of adding a new one.
|
|
49
|
+
* @param [props.to] Link URL.
|
|
50
|
+
* @param [props.activeClassName] **`<NavLink>`** only: CSS class(es)
|
|
51
|
+
* to apply to rendered link when it is active.
|
|
52
|
+
* @param [props.activeStyle] **`<NavLink>`** only: CSS styles
|
|
53
|
+
* to apply to the rendered link when it is active.
|
|
54
|
+
* @param [props.exact] **`<NavLink>`** only: if `true`, the active
|
|
55
|
+
* class/style will only be applied if the location is matched exactly.
|
|
56
|
+
* @param [props.isActive] **`<NavLink>`** only: Add extra
|
|
57
|
+
* logic for determining whether the link is active. This should be used if you
|
|
58
|
+
* want to do more than verify that the link’s pathname matches the current URL
|
|
59
|
+
* pathname.
|
|
60
|
+
* @param [props.location] **`<NavLink>`** only: `isActive` compares
|
|
61
|
+
* current history location (usually the current browser URL). To compare to
|
|
62
|
+
* a different location, a custom `location` can be passed.
|
|
63
|
+
* @param [props.strict] **`<NavLink>`** only: . When `true`, trailing
|
|
64
|
+
* slash on a location’s pathname will be taken into consideration when
|
|
65
|
+
* determining if the location matches the current URL. See the `<Route strict>`
|
|
66
|
+
* documentation for more information.
|
|
67
|
+
*/
|
|
68
|
+
const GenericLink: React.FunctionComponent<PropsT> = ({
|
|
69
|
+
children,
|
|
70
|
+
className,
|
|
71
|
+
disabled,
|
|
72
|
+
enforceA,
|
|
73
|
+
keepScrollPosition,
|
|
74
|
+
onClick,
|
|
75
|
+
onMouseDown,
|
|
76
|
+
openNewTab,
|
|
77
|
+
replace,
|
|
78
|
+
routerLinkType,
|
|
79
|
+
to,
|
|
80
|
+
...rest
|
|
81
|
+
}) => {
|
|
82
|
+
/* Renders Link as <a> element if:
|
|
83
|
+
* - It is opted explicitely by `enforceA` prop;
|
|
84
|
+
* - It should be opened in a new tab;
|
|
85
|
+
* - It is an absolte URL (starts with http:// or https://);
|
|
86
|
+
* - It is anchor link (starts with #). */
|
|
87
|
+
if (disabled || enforceA || openNewTab || (to as string)?.match(/^(#|(https?|mailto):)/)) {
|
|
88
|
+
return (
|
|
89
|
+
<a
|
|
90
|
+
className={className}
|
|
91
|
+
// TODO: This requires a fix: disabled is not really an attribute of <a>
|
|
92
|
+
// tag, thus for disabled option we rather should render a plain text
|
|
93
|
+
// styled as a link.
|
|
94
|
+
// disabled={disabled}
|
|
95
|
+
href={to as string}
|
|
96
|
+
onClick={disabled ? (e) => e.preventDefault() : onClick}
|
|
97
|
+
onMouseDown={disabled ? (e) => e.preventDefault() : onMouseDown}
|
|
98
|
+
rel="noopener noreferrer"
|
|
99
|
+
styleName="link"
|
|
100
|
+
target={openNewTab ? '_blank' : ''}
|
|
101
|
+
>
|
|
102
|
+
{children}
|
|
103
|
+
</a>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const L = routerLinkType as typeof NavLink;
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<L
|
|
111
|
+
className={className}
|
|
112
|
+
// disabled
|
|
113
|
+
onMouseDown={onMouseDown}
|
|
114
|
+
replace={replace}
|
|
115
|
+
to={to!}
|
|
116
|
+
onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {
|
|
117
|
+
// Executes the user-provided event handler, if any.
|
|
118
|
+
if (onClick) onClick(e);
|
|
119
|
+
|
|
120
|
+
// By default, clicking the link scrolls the page to beginning.
|
|
121
|
+
if (!keepScrollPosition) window.scroll(0, 0);
|
|
122
|
+
}}
|
|
123
|
+
{...rest} // eslint-disable-line react/jsx-props-no-spreading
|
|
124
|
+
>
|
|
125
|
+
{children}
|
|
126
|
+
</L>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
GenericLink.defaultProps = {
|
|
131
|
+
children: null,
|
|
132
|
+
className: '',
|
|
133
|
+
disabled: false,
|
|
134
|
+
enforceA: false,
|
|
135
|
+
keepScrollPosition: false,
|
|
136
|
+
onClick: undefined,
|
|
137
|
+
onMouseDown: undefined,
|
|
138
|
+
openNewTab: false,
|
|
139
|
+
replace: false,
|
|
140
|
+
to: '',
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
GenericLink.propTypes = {
|
|
144
|
+
children: PT.node,
|
|
145
|
+
className: PT.string,
|
|
146
|
+
disabled: PT.bool,
|
|
147
|
+
enforceA: PT.bool,
|
|
148
|
+
keepScrollPosition: PT.bool,
|
|
149
|
+
onClick: PT.func,
|
|
150
|
+
onMouseDown: PT.func,
|
|
151
|
+
openNewTab: PT.bool,
|
|
152
|
+
replace: PT.bool,
|
|
153
|
+
routerLinkType: PT.elementType.isRequired,
|
|
154
|
+
to: PT.oneOfType([PT.object, PT.string]),
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export default GenericLink;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import PT from 'prop-types';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
|
|
4
|
+
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
5
|
+
|
|
6
|
+
import defaultTheme from './theme.scss';
|
|
7
|
+
|
|
8
|
+
type PropsT = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
9
|
+
label?: string;
|
|
10
|
+
theme: Theme & {
|
|
11
|
+
container?: string;
|
|
12
|
+
input?: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Themeable input field, based on the standard HTML `<input>` element.
|
|
19
|
+
* @param [props]
|
|
20
|
+
* @param [props.label] Input label.
|
|
21
|
+
* @param [props.theme] _Ad hoc_ theme.
|
|
22
|
+
* @param [props...] [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)
|
|
23
|
+
* @param [props...] Any other properties are passed to the underlying
|
|
24
|
+
* `<input>` element.
|
|
25
|
+
*/
|
|
26
|
+
const Input = forwardRef<HTMLInputElement, PropsT>((
|
|
27
|
+
{
|
|
28
|
+
label,
|
|
29
|
+
theme,
|
|
30
|
+
...rest
|
|
31
|
+
}: PropsT,
|
|
32
|
+
ref,
|
|
33
|
+
) => (
|
|
34
|
+
<span className={theme.container}>
|
|
35
|
+
{ label === undefined ? null : <p className={theme.label}>{label}</p> }
|
|
36
|
+
<input
|
|
37
|
+
className={theme.input}
|
|
38
|
+
ref={ref}
|
|
39
|
+
{...rest} // eslint-disable-line react/jsx-props-no-spreading
|
|
40
|
+
/>
|
|
41
|
+
</span>
|
|
42
|
+
));
|
|
43
|
+
|
|
44
|
+
const ThemedInput = themed(Input, 'Input', [
|
|
45
|
+
'container',
|
|
46
|
+
'input',
|
|
47
|
+
'label',
|
|
48
|
+
], defaultTheme);
|
|
49
|
+
|
|
50
|
+
Input.propTypes = {
|
|
51
|
+
label: PT.string,
|
|
52
|
+
theme: ThemedInput.themeType.isRequired,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
Input.defaultProps = {
|
|
56
|
+
label: undefined,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default ThemedInput;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
*,
|
|
2
|
+
.context,
|
|
3
|
+
.ad.hoc {
|
|
4
|
+
&.container {
|
|
5
|
+
align-items: center;
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
margin: 0.1em;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&.input {
|
|
11
|
+
border: 1px solid gray;
|
|
12
|
+
border-radius: 0.3em;
|
|
13
|
+
cursor: text;
|
|
14
|
+
font: inherit;
|
|
15
|
+
outline: none;
|
|
16
|
+
padding: 0.3em 0.3em calc(0.3em + 1px);
|
|
17
|
+
|
|
18
|
+
&:focus {
|
|
19
|
+
border-color: blue;
|
|
20
|
+
box-shadow: 0 0 3px 1px lightblue;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&.label {
|
|
25
|
+
margin: 0 0.6em 0 1.5em;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Link wraps around React Router's Link component, to automatically replace
|
|
3
|
+
* it by the regular <a> element when:
|
|
4
|
+
* - The target reference points to another domain;
|
|
5
|
+
* - User opts to open the reference in a new tab;
|
|
6
|
+
* - User explicitely opts to use <a>.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Link as RrLink } from 'react-router-dom';
|
|
10
|
+
|
|
11
|
+
import GenericLink, { type PropsT as GenericLinkPropsT } from './GenericLink';
|
|
12
|
+
|
|
13
|
+
type PropsT = Omit<GenericLinkPropsT, 'routerLinkType'>;
|
|
14
|
+
|
|
15
|
+
const Link: React.FunctionComponent<PropsT> = (props) => (
|
|
16
|
+
/* eslint-disable react/jsx-props-no-spreading */
|
|
17
|
+
<GenericLink {...props} routerLinkType={RrLink} />
|
|
18
|
+
/* eslint-enable react/jsx-props-no-spreading */
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export default Link;
|