@dr.pogodin/react-utils 1.47.5 → 1.48.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/build/development/index.js +1 -1
- package/build/development/index.js.map +1 -1
- package/build/development/server/server.js +0 -1
- package/build/development/server/server.js.map +1 -1
- package/build/development/shared/components/Button/index.js +13 -9
- package/build/development/shared/components/Button/index.js.map +1 -1
- package/build/development/shared/components/Checkbox/index.js +8 -7
- package/build/development/shared/components/Checkbox/index.js.map +1 -1
- package/build/development/shared/components/Input/index.js +14 -12
- package/build/development/shared/components/Input/index.js.map +1 -1
- package/build/development/shared/components/Modal/index.js +15 -3
- package/build/development/shared/components/Modal/index.js.map +1 -1
- package/build/development/shared/components/PageLayout/index.js +18 -15
- package/build/development/shared/components/PageLayout/index.js.map +1 -1
- package/build/development/shared/components/TextArea/index.js +9 -8
- package/build/development/shared/components/TextArea/index.js.map +1 -1
- package/build/development/shared/components/Throbber/index.js +15 -12
- package/build/development/shared/components/Throbber/index.js.map +1 -1
- package/build/development/shared/components/WithTooltip/index.js +6 -6
- package/build/development/shared/components/WithTooltip/index.js.map +1 -1
- package/build/development/shared/components/YouTubeVideo/index.js +6 -5
- package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/index.js +13 -12
- package/build/development/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/NativeDropdown/index.js +11 -10
- package/build/development/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/Switch/index.js +9 -9
- package/build/development/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/development/shared/components/selectors/common.js.map +1 -1
- package/build/development/shared/components/selectors/index.js +1 -1
- package/build/development/shared/components/selectors/index.js.map +1 -1
- package/build/development/shared/utils/index.js +2 -5
- package/build/development/shared/utils/index.js.map +1 -1
- package/build/development/shared/utils/jest/E2eSsrEnv.js +0 -1
- package/build/development/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/production/index.js +1 -1
- package/build/production/index.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 -8
- package/build/production/shared/components/Button/index.js.map +1 -1
- package/build/production/shared/components/Checkbox/index.js +1 -1
- package/build/production/shared/components/Checkbox/index.js.map +1 -1
- package/build/production/shared/components/Input/index.js +6 -6
- 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/PageLayout/index.js +2 -2
- package/build/production/shared/components/PageLayout/index.js.map +1 -1
- package/build/production/shared/components/TextArea/index.js +4 -4
- 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/index.js +3 -3
- package/build/production/shared/components/WithTooltip/index.js.map +1 -1
- package/build/production/shared/components/YouTubeVideo/index.js +4 -4
- package/build/production/shared/components/YouTubeVideo/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.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/index.js +1 -1
- package/build/production/shared/utils/index.js.map +1 -1
- package/build/production/shared/utils/jest/E2eSsrEnv.js +1 -1
- package/build/production/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/types-code/index.d.ts +1 -1
- package/build/types-code/shared/components/Button/index.d.ts +6 -10
- package/build/types-code/shared/components/Checkbox/index.d.ts +4 -3
- package/build/types-code/shared/components/Input/index.d.ts +12 -4
- package/build/types-code/shared/components/Modal/index.d.ts +6 -3
- package/build/types-code/shared/components/PageLayout/index.d.ts +19 -4
- package/build/types-code/shared/components/TextArea/index.d.ts +4 -4
- package/build/types-code/shared/components/Throbber/index.d.ts +13 -3
- package/build/types-code/shared/components/WithTooltip/index.d.ts +18 -4
- package/build/types-code/shared/components/YouTubeVideo/index.d.ts +20 -4
- package/build/types-code/shared/components/selectors/CustomDropdown/index.d.ts +3 -2
- package/build/types-code/shared/components/selectors/NativeDropdown/index.d.ts +22 -2
- package/build/types-code/shared/components/selectors/Switch/index.d.ts +7 -6
- package/build/types-code/shared/components/selectors/common.d.ts +2 -3
- package/build/types-code/shared/components/selectors/index.d.ts +2 -2
- package/build/types-code/shared/utils/index.d.ts +2 -7
- package/build/web/index.js +1 -1
- package/build/web/index.js.map +1 -1
- package/build/web/server/server.js +0 -1
- package/build/web/server/server.js.map +1 -1
- package/build/web/shared/components/Button/index.js +13 -9
- package/build/web/shared/components/Button/index.js.map +1 -1
- package/build/web/shared/components/Checkbox/index.js +8 -7
- package/build/web/shared/components/Checkbox/index.js.map +1 -1
- package/build/web/shared/components/Input/index.js +14 -12
- package/build/web/shared/components/Input/index.js.map +1 -1
- package/build/web/shared/components/Modal/index.js +15 -3
- package/build/web/shared/components/Modal/index.js.map +1 -1
- package/build/web/shared/components/PageLayout/index.js +18 -15
- package/build/web/shared/components/PageLayout/index.js.map +1 -1
- package/build/web/shared/components/TextArea/index.js +9 -8
- package/build/web/shared/components/TextArea/index.js.map +1 -1
- package/build/web/shared/components/Throbber/index.js +15 -12
- package/build/web/shared/components/Throbber/index.js.map +1 -1
- package/build/web/shared/components/WithTooltip/index.js +6 -6
- package/build/web/shared/components/WithTooltip/index.js.map +1 -1
- package/build/web/shared/components/YouTubeVideo/index.js +6 -5
- package/build/web/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/web/shared/components/selectors/CustomDropdown/index.js +13 -12
- package/build/web/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/web/shared/components/selectors/NativeDropdown/index.js +11 -10
- package/build/web/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/web/shared/components/selectors/Switch/index.js +9 -9
- package/build/web/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/web/shared/components/selectors/common.js.map +1 -1
- package/build/web/shared/components/selectors/index.js +1 -1
- package/build/web/shared/components/selectors/index.js.map +1 -1
- package/build/web/shared/utils/index.js +2 -5
- package/build/web/shared/utils/index.js.map +1 -1
- package/build/web/shared/utils/jest/E2eSsrEnv.js +0 -1
- package/build/web/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/config/babel/webpack.js +1 -1
- package/package.json +15 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useEffect","useLayoutEffect","useRef","useState","
|
|
1
|
+
{"version":3,"file":"index.js","names":["useEffect","useLayoutEffect","useRef","useState","useTheme","defaultTheme","jsx","_jsx","jsxs","_jsxs","TextArea","disabled","error","label","onBlur","onChange","onKeyDown","placeholder","testId","theme","value","custom","hiddenAreaRef","height","setHeight","textAreaRef","localValue","setLocalValue","undefined","el","current","cb","scrollHeight","observer","ResizeObserver","observe","disconnect","containerClassName","container","className","onFocus","focus","children","textarea","hidden","readOnly","ref","tabIndex","process","env","NODE_ENV","e","target","style","errorMessage"],"sources":["../../../../../src/shared/components/TextArea/index.tsx"],"sourcesContent":["import {\n type ChangeEventHandler,\n type FocusEventHandler,\n type FunctionComponent,\n type KeyboardEventHandler,\n type ReactNode,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { type Theme, useTheme } from '@dr.pogodin/react-themes';\n\nimport defaultTheme from './style.scss';\n\ntype ThemeKeyT = 'container' | 'error' | 'errorMessage' | 'hidden' | 'label'\n | 'textarea';\n\ntype Props = {\n disabled?: boolean;\n error?: ReactNode;\n label?: string;\n onBlur?: FocusEventHandler<HTMLTextAreaElement>;\n onChange?: ChangeEventHandler<HTMLTextAreaElement>;\n onKeyDown?: KeyboardEventHandler<HTMLTextAreaElement>;\n placeholder?: string;\n testId?: string;\n theme?: Theme<ThemeKeyT>;\n value?: string;\n};\n\nconst TextArea: FunctionComponent<Props> = ({\n disabled,\n error,\n label,\n onBlur,\n onChange,\n onKeyDown,\n placeholder,\n testId,\n theme,\n value,\n}) => {\n const custom = useTheme('TextArea', defaultTheme, theme);\n\n const hiddenAreaRef = useRef<HTMLTextAreaElement>(null);\n const [height, setHeight] = useState<number | undefined>();\n\n const textAreaRef = useRef<HTMLTextAreaElement>(null);\n\n const [localValue, setLocalValue] = useState(value ?? '');\n if (value !== undefined && localValue !== value) setLocalValue(value);\n\n // This resizes text area's height when its width is changed for any reason.\n useEffect(() => {\n const el = hiddenAreaRef.current;\n if (!el) return undefined;\n\n const cb = () => {\n setHeight(el.scrollHeight);\n };\n const observer = new ResizeObserver(cb);\n observer.observe(el);\n\n return () => {\n observer.disconnect();\n };\n }, []);\n\n // Resizes the text area when its content is modified.\n //\n // NOTE: useLayoutEffect() instead of useEffect() makes difference here,\n // as it helps to avoid visible \"content/height\" jumps (i.e. with just\n // useEffect() it becomes visible how the content is modified first,\n // and then input height is incremented, if necessary).\n // See: https://github.com/birdofpreyru/react-utils/issues/313\n useLayoutEffect(() => {\n const el = hiddenAreaRef.current;\n if (el) setHeight(el.scrollHeight);\n }, [localValue]);\n\n let containerClassName = custom.container;\n if (error) containerClassName += ` ${custom.error}`;\n\n return (\n <div\n className={containerClassName}\n onFocus={() => {\n textAreaRef.current?.focus();\n }}\n >\n {label === undefined ? null : <div className={custom.label}>{label}</div>}\n <textarea\n className={`${custom.textarea} ${custom.hidden}`}\n\n // This text area is hidden underneath the primary one below,\n // and it is used for text measurements, to implement auto-scaling\n // of the primary textarea's height.\n readOnly\n ref={hiddenAreaRef}\n\n // The \"-1\" value of \"tabIndex\" removes this hidden text area from\n // the tab-focus-chain.\n tabIndex={-1}\n\n // NOTE: With empty string value (\"\") the scrolling height of this text\n // area is zero, thus collapsing <TextArea> height below the single line\n // input height. To avoid it we fallback to whitespace (\" \") character\n // here.\n value={localValue || ' '}\n />\n <textarea\n className={custom.textarea}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n disabled={disabled}\n onBlur={onBlur}\n\n // When value is \"undefined\" the text area is not-managed, and we should\n // manage it internally for the measurement / resizing functionality\n // to work.\n onChange={\n value === undefined\n ? (e) => {\n setLocalValue(e.target.value);\n } : onChange\n }\n onKeyDown={onKeyDown}\n placeholder={placeholder}\n ref={textAreaRef}\n style={{ height }}\n value={localValue}\n />\n {error && error !== true\n ? <div className={custom.errorMessage}>{error}</div>\n : null}\n </div>\n );\n};\n\nexport default TextArea;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useTheme } from '@dr.pogodin/react-themes';
|
|
2
2
|
const defaultTheme = {
|
|
3
3
|
"context": "-dr-pogodin-react-utils___build-web-shared-components-Throbber-theme___context___eVCJf-",
|
|
4
4
|
"ad": "-dr-pogodin-react-utils___build-web-shared-components-Throbber-theme___ad___CU2B6H",
|
|
@@ -19,15 +19,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
19
19
|
*/
|
|
20
20
|
const Throbber = ({
|
|
21
21
|
theme
|
|
22
|
-
}) =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
className:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
}) => {
|
|
23
|
+
const custom = useTheme('Throbber', defaultTheme, theme);
|
|
24
|
+
return /*#__PURE__*/_jsxs("span", {
|
|
25
|
+
className: custom.container,
|
|
26
|
+
children: [/*#__PURE__*/_jsx("span", {
|
|
27
|
+
className: custom.circle
|
|
28
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
29
|
+
className: custom.circle
|
|
30
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
31
|
+
className: custom.circle
|
|
32
|
+
})]
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
export default Throbber;
|
|
33
36
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["
|
|
1
|
+
{"version":3,"file":"index.js","names":["useTheme","defaultTheme","jsx","_jsx","jsxs","_jsxs","Throbber","theme","custom","className","container","children","circle"],"sources":["../../../../../src/shared/components/Throbber/index.tsx"],"sourcesContent":["import type { FunctionComponent } from 'react';\n\nimport { type Theme, useTheme } from '@dr.pogodin/react-themes';\n\nimport defaultTheme from './theme.scss';\n\ntype ThemeKeyT = 'bouncing' | 'circle' | 'container';\n\ntype PropsT = {\n theme?: Theme<ThemeKeyT>;\n};\n\n/**\n * Throbber is an \"action in progress\" indicator, which renders\n * three bouncing circles as a simple pending activity indicator,\n * and can be further themed to a certain degree.\n * @param {object} [props] Component properties.\n * @param {ThrobberTheme} [props.theme] _Ad hoc_ theme.\n * @param {...any} [props....]\n * [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)\n */\nconst Throbber: FunctionComponent<PropsT> = ({ theme }) => {\n const custom = useTheme('Throbber', defaultTheme, theme);\n\n return (\n <span className={custom.container}>\n <span className={custom.circle} />\n <span className={custom.circle} />\n <span className={custom.circle} />\n </span>\n );\n};\n\nexport default Throbber;\n"],"mappings":"AAEA,SAAqBA,QAAQ,QAAQ,0BAA0B;AAAA,MAAAC,YAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAEvB,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAQxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,QAAmC,GAAGA,CAAC;EAAEC;AAAM,CAAC,KAAK;EACzD,MAAMC,MAAM,GAAGR,QAAQ,CAAC,UAAU,EAAEC,YAAY,EAAEM,KAAK,CAAC;EAExD,oBACEF,KAAA;IAAMI,SAAS,EAAED,MAAM,CAACE,SAAU;IAAAC,QAAA,gBAChCR,IAAA;MAAMM,SAAS,EAAED,MAAM,CAACI;IAAO,CAAE,CAAC,eAClCT,IAAA;MAAMM,SAAS,EAAED,MAAM,CAACI;IAAO,CAAE,CAAC,eAClCT,IAAA;MAAMM,SAAS,EAAED,MAAM,CAACI;IAAO,CAAE,CAAC;EAAA,CAC9B,CAAC;AAEX,CAAC;AAED,eAAeN,QAAQ","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* global window */
|
|
2
2
|
|
|
3
3
|
import { useEffect, useRef, useState } from 'react';
|
|
4
|
-
import
|
|
4
|
+
import { useTheme } from '@dr.pogodin/react-themes';
|
|
5
5
|
import Tooltip, { PLACEMENTS } from "./Tooltip.js";
|
|
6
6
|
const defaultTheme = {
|
|
7
7
|
"ad": "-dr-pogodin-react-utils___build-web-shared-components-WithTooltip-default-theme___ad___n6OiU9",
|
|
@@ -27,12 +27,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
27
27
|
* _e.g._ a tooltip text. This will be the tooltip content.
|
|
28
28
|
* @param {WithTooltipTheme} props.theme _Ad hoc_ theme.
|
|
29
29
|
*/
|
|
30
|
-
const
|
|
30
|
+
const WithTooltip = ({
|
|
31
31
|
children,
|
|
32
32
|
placement = PLACEMENTS.ABOVE_CURSOR,
|
|
33
33
|
tip,
|
|
34
34
|
theme
|
|
35
35
|
}) => {
|
|
36
|
+
const custom = useTheme('WithTooltip', defaultTheme, theme);
|
|
36
37
|
const {
|
|
37
38
|
current: heap
|
|
38
39
|
} = useRef({
|
|
@@ -92,7 +93,7 @@ const Wrapper = ({
|
|
|
92
93
|
return undefined;
|
|
93
94
|
}, [heap.lastCursorX, heap.lastCursorY, placement, showTooltip, tip]);
|
|
94
95
|
return /*#__PURE__*/_jsxs("div", {
|
|
95
|
-
className:
|
|
96
|
+
className: custom.wrapper,
|
|
96
97
|
onClick: () => {
|
|
97
98
|
if (heap.timerId) {
|
|
98
99
|
clearTimeout(heap.timerId);
|
|
@@ -113,13 +114,12 @@ const Wrapper = ({
|
|
|
113
114
|
role: "presentation",
|
|
114
115
|
children: [showTooltip && tip !== null ? /*#__PURE__*/_jsx(Tooltip, {
|
|
115
116
|
ref: tooltipRef,
|
|
116
|
-
theme:
|
|
117
|
+
theme: custom,
|
|
117
118
|
children: tip
|
|
118
119
|
}) : null, children]
|
|
119
120
|
});
|
|
120
121
|
};
|
|
121
|
-
const
|
|
122
|
-
const e = ThemedWrapper;
|
|
122
|
+
const e = WithTooltip;
|
|
123
123
|
e.PLACEMENTS = PLACEMENTS;
|
|
124
124
|
export default e;
|
|
125
125
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useEffect","useRef","useState","
|
|
1
|
+
{"version":3,"file":"index.js","names":["useEffect","useRef","useState","useTheme","Tooltip","PLACEMENTS","defaultTheme","jsx","_jsx","jsxs","_jsxs","WithTooltip","children","placement","ABOVE_CURSOR","tip","theme","custom","current","heap","lastCursorX","lastCursorY","timerId","undefined","triggeredByTouch","tooltipRef","wrapperRef","showTooltip","setShowTooltip","updatePortalPosition","cursorX","cursorY","wrapperRect","getBoundingClientRect","left","right","top","bottom","pointTo","window","scrollX","scrollY","setTimeout","listener","addEventListener","removeEventListener","className","wrapper","onClick","clearTimeout","onMouseLeave","onMouseMove","e","clientX","clientY","onTouchStart","ref","role"],"sources":["../../../../../src/shared/components/WithTooltip/index.tsx"],"sourcesContent":["/* global window */\n\nimport {\n type FunctionComponent,\n type ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { type Theme, useTheme } from '@dr.pogodin/react-themes';\n\nimport Tooltip, {\n type ThemeKeysT as TooltipThemeKeysT,\n PLACEMENTS,\n} from './Tooltip';\n\nimport defaultTheme from './default-theme.scss';\n\ntype PropsT = {\n children?: ReactNode;\n placement?: PLACEMENTS;\n tip?: ReactNode;\n theme?: Theme<'wrapper' | TooltipThemeKeysT>;\n};\n\ntype TooltipRefT = {\n pointTo: (\n x: number,\n y: number,\n placement: PLACEMENTS,\n wrapperRef: HTMLDivElement,\n ) => void;\n};\n\ntype HeapT = {\n lastCursorX: number;\n lastCursorY: number;\n triggeredByTouch: boolean;\n timerId?: NodeJS.Timeout;\n};\n\n/**\n * Implements a simple to use and themeable tooltip component, _e.g._\n * ```js\n * <WithTooltip tip=\"This is example tooltip.\">\n * <p>Hover to see the tooltip.</p>\n * </WithTooltip>\n * ```\n * **Children:** Children are rendered in the place of `<WithTooltip>`,\n * and when hovered the tooltip is shown. By default the wrapper itself is\n * `<div>` block with `display: inline-block`.\n * @param tip – Anything React is able to render,\n * _e.g._ a tooltip text. This will be the tooltip content.\n * @param {WithTooltipTheme} props.theme _Ad hoc_ theme.\n */\nconst WithTooltip: FunctionComponent<PropsT> = ({\n children,\n placement = PLACEMENTS.ABOVE_CURSOR,\n tip,\n theme,\n}) => {\n const custom = useTheme('WithTooltip', defaultTheme, theme);\n\n const { current: heap } = useRef<HeapT>({\n lastCursorX: 0,\n lastCursorY: 0,\n timerId: undefined,\n triggeredByTouch: false,\n });\n const tooltipRef = useRef<TooltipRefT>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const [showTooltip, setShowTooltip] = useState(false);\n\n const updatePortalPosition = (cursorX: number, cursorY: number) => {\n if (showTooltip) {\n const wrapperRect = wrapperRef.current!.getBoundingClientRect();\n if (\n cursorX < wrapperRect.left\n || cursorX > wrapperRect.right\n || cursorY < wrapperRect.top\n || cursorY > wrapperRect.bottom\n ) {\n setShowTooltip(false);\n } else if (tooltipRef.current) {\n tooltipRef.current.pointTo(\n cursorX + window.scrollX,\n cursorY + window.scrollY,\n placement,\n wrapperRef.current!,\n );\n }\n } else {\n heap.lastCursorX = cursorX;\n heap.lastCursorY = cursorY;\n\n // If tooltip was triggered by a touch, we delay its opening by a bit,\n // to ensure it was not a touch-click - in the case of touch click we\n // want to do the click, rather than show the tooltip, and the delay\n // gives click handler a chance to abort the tooltip openning.\n if (heap.triggeredByTouch) {\n heap.timerId ??= setTimeout(() => {\n heap.triggeredByTouch = false;\n heap.timerId = undefined;\n setShowTooltip(true);\n }, 300);\n\n // Otherwise we can just open the tooltip right away.\n } else setShowTooltip(true);\n }\n };\n\n useEffect(() => {\n if (showTooltip && tip !== null) {\n // This is necessary to ensure that even when a single mouse event\n // arrives to a tool-tipped component, the tooltip is correctly positioned\n // once opened (because similar call above does not have effect until\n // the tooltip is fully mounted, and that is delayed to future rendering\n // cycle due to the implementation).\n if (tooltipRef.current) {\n tooltipRef.current.pointTo(\n heap.lastCursorX + window.scrollX,\n heap.lastCursorY + window.scrollY,\n placement,\n wrapperRef.current!,\n );\n }\n\n const listener = () => {\n setShowTooltip(false);\n };\n window.addEventListener('scroll', listener);\n return () => {\n window.removeEventListener('scroll', listener);\n };\n }\n return undefined;\n }, [\n heap.lastCursorX,\n heap.lastCursorY,\n placement,\n showTooltip,\n tip,\n ]);\n\n return (\n <div\n className={custom.wrapper}\n onClick={() => {\n if (heap.timerId) {\n clearTimeout(heap.timerId);\n heap.timerId = undefined;\n heap.triggeredByTouch = false;\n }\n }}\n onMouseLeave={() => {\n setShowTooltip(false);\n }}\n onMouseMove={(e) => {\n updatePortalPosition(e.clientX, e.clientY);\n }}\n onTouchStart={() => {\n heap.triggeredByTouch = true;\n }}\n ref={wrapperRef}\n role=\"presentation\"\n >\n {\n showTooltip && tip !== null\n ? <Tooltip ref={tooltipRef} theme={custom}>{tip}</Tooltip>\n : null\n }\n {children}\n </div>\n );\n};\n\ntype ExportT = typeof WithTooltip & {\n PLACEMENTS: typeof PLACEMENTS;\n};\n\nconst e: ExportT = WithTooltip as ExportT;\n\ne.PLACEMENTS = PLACEMENTS;\n\nexport default e;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import qs from 'qs';
|
|
2
|
-
import
|
|
2
|
+
import { useTheme } from '@dr.pogodin/react-themes';
|
|
3
3
|
import Throbber from "../Throbber/index.js";
|
|
4
|
-
const
|
|
4
|
+
const defaultTheme = {
|
|
5
5
|
"context": "-dr-pogodin-react-utils___build-web-shared-components-YouTubeVideo-base___context___Pa7GiX",
|
|
6
6
|
"ad": "-dr-pogodin-react-utils___build-web-shared-components-YouTubeVideo-base___ad___NikZ57",
|
|
7
7
|
"hoc": "-dr-pogodin-react-utils___build-web-shared-components-YouTubeVideo-base___hoc___FydyFQ",
|
|
@@ -36,6 +36,7 @@ const YouTubeVideo = ({
|
|
|
36
36
|
theme,
|
|
37
37
|
title
|
|
38
38
|
}) => {
|
|
39
|
+
const custom = useTheme('YouTubeVideo', defaultTheme, theme);
|
|
39
40
|
const srcParts = src.split('?');
|
|
40
41
|
let [url] = srcParts;
|
|
41
42
|
const [, queryString] = srcParts;
|
|
@@ -50,18 +51,18 @@ const YouTubeVideo = ({
|
|
|
50
51
|
// More query parameters can be exposed via the component props.
|
|
51
52
|
|
|
52
53
|
return /*#__PURE__*/_jsxs("div", {
|
|
53
|
-
className:
|
|
54
|
+
className: custom.container,
|
|
54
55
|
children: [/*#__PURE__*/_jsx(Throbber, {
|
|
55
56
|
theme: throbberTheme
|
|
56
57
|
}), /*#__PURE__*/_jsx("iframe", {
|
|
57
58
|
// eslint-disable-line react/iframe-missing-sandbox
|
|
58
59
|
allow: "autoplay",
|
|
59
60
|
allowFullScreen: true,
|
|
60
|
-
className:
|
|
61
|
+
className: custom.video,
|
|
61
62
|
src: url,
|
|
62
63
|
title: title
|
|
63
64
|
})]
|
|
64
65
|
});
|
|
65
66
|
};
|
|
66
|
-
export default
|
|
67
|
+
export default YouTubeVideo;
|
|
67
68
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["qs","
|
|
1
|
+
{"version":3,"file":"index.js","names":["qs","useTheme","Throbber","defaultTheme","throbberTheme","jsx","_jsx","jsxs","_jsxs","YouTubeVideo","autoplay","src","theme","title","custom","srcParts","split","url","queryString","query","parse","videoId","v","match","stringify","className","container","children","allow","allowFullScreen","video"],"sources":["../../../../../src/shared/components/YouTubeVideo/index.tsx"],"sourcesContent":["import qs from 'qs';\nimport type { FunctionComponent } from 'react';\n\nimport { type Theme, useTheme } from '@dr.pogodin/react-themes';\n\nimport Throbber from 'components/Throbber';\n\nimport defaultTheme from './base.scss';\nimport throbberTheme from './throbber.scss';\n\ntype ThemeT = Theme<'container' | 'video'>;\n\ntype PropsT = {\n autoplay?: boolean;\n src: string;\n theme?: ThemeT;\n title?: string;\n};\n\n/**\n * A component for embeding a YouTube video.\n * @param [props] Component properties.\n * @param [props.autoplay] If `true` the video will start to play\n * automatically once loaded.\n * @param [props.src] URL of the video to play. Can be in any of\n * the following formats, and keeps any additional query parameters understood\n * by the YouTube IFrame player:\n * - `https://www.youtube.com/watch?v=NdF6Rmt6Ado`\n * - `https://youtu.be/NdF6Rmt6Ado`\n * - `https://www.youtube.com/embed/NdF6Rmt6Ado`\n * @param [props.theme] _Ad hoc_ theme.\n * @param [props.title] The `title` attribute to add to the player\n * IFrame.\n */\nconst YouTubeVideo: FunctionComponent<PropsT> = ({\n autoplay,\n src,\n theme,\n title,\n}) => {\n const custom = useTheme('YouTubeVideo', defaultTheme, theme);\n\n const srcParts = src.split('?');\n let [url] = srcParts;\n const [, queryString] = srcParts;\n const query = queryString ? qs.parse(queryString) : {};\n\n const videoId = query.v ?? url?.match(/\\/([a-zA-Z0-9-_]*)$/)?.[1];\n url = `https://www.youtube.com/embed/${videoId as string}`;\n\n delete query.v;\n query.autoplay = autoplay ? '1' : '0';\n url += `?${qs.stringify(query)}`;\n\n // TODO: https://developers.google.com/youtube/player_parameters\n // More query parameters can be exposed via the component props.\n\n return (\n <div className={custom.container}>\n <Throbber theme={throbberTheme} />\n {/* TODO: I guess, we better add the sanbox, but right now I don't have\n time to carefully explore which restrictions should be lifted to allow\n embed YouTube player to work... sometime later we'll take care of it */\n }\n <iframe // eslint-disable-line react/iframe-missing-sandbox\n allow=\"autoplay\"\n allowFullScreen\n className={custom.video}\n src={url}\n title={title}\n />\n </div>\n );\n};\n\nexport default YouTubeVideo;\n"],"mappings":"AAAA,OAAOA,EAAE,MAAM,IAAI;AAGnB,SAAqBC,QAAQ,QAAQ,0BAA0B;AAAA,OAExDC,QAAQ;AAAA,MAAAC,YAAA;EAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAAA,MAAAC,aAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAG6B,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAW5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,YAAuC,GAAGA,CAAC;EAC/CC,QAAQ;EACRC,GAAG;EACHC,KAAK;EACLC;AACF,CAAC,KAAK;EACJ,MAAMC,MAAM,GAAGb,QAAQ,CAAC,cAAc,EAAEE,YAAY,EAAES,KAAK,CAAC;EAE5D,MAAMG,QAAQ,GAAGJ,GAAG,CAACK,KAAK,CAAC,GAAG,CAAC;EAC/B,IAAI,CAACC,GAAG,CAAC,GAAGF,QAAQ;EACpB,MAAM,GAAGG,WAAW,CAAC,GAAGH,QAAQ;EAChC,MAAMI,KAAK,GAAGD,WAAW,GAAGlB,EAAE,CAACoB,KAAK,CAACF,WAAW,CAAC,GAAG,CAAC,CAAC;EAEtD,MAAMG,OAAO,GAAGF,KAAK,CAACG,CAAC,IAAIL,GAAG,EAAEM,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;EACjEN,GAAG,GAAG,iCAAiCI,OAAO,EAAY;EAE1D,OAAOF,KAAK,CAACG,CAAC;EACdH,KAAK,CAACT,QAAQ,GAAGA,QAAQ,GAAG,GAAG,GAAG,GAAG;EACrCO,GAAG,IAAI,IAAIjB,EAAE,CAACwB,SAAS,CAACL,KAAK,CAAC,EAAE;;EAEhC;EACA;;EAEA,oBACEX,KAAA;IAAKiB,SAAS,EAAEX,MAAM,CAACY,SAAU;IAAAC,QAAA,gBAC/BrB,IAAA,CAACJ,QAAQ;MAACU,KAAK,EAAER;IAAc,CAAE,CAAC,eAKlCE,IAAA;MAAQ;MACNsB,KAAK,EAAC,UAAU;MAChBC,eAAe;MACfJ,SAAS,EAAEX,MAAM,CAACgB,KAAM;MACxBnB,GAAG,EAAEM,GAAI;MACTJ,KAAK,EAAEA;IAAM,CACd,CAAC;EAAA,CACC,CAAC;AAEV,CAAC;AAED,eAAeJ,YAAY","ignoreList":[]}
|
|
@@ -2,7 +2,7 @@ import "core-js/modules/es.iterator.filter.js";
|
|
|
2
2
|
import "core-js/modules/es.iterator.constructor.js";
|
|
3
3
|
import "core-js/modules/es.iterator.filter.js";
|
|
4
4
|
import { useEffect, useRef, useState } from 'react';
|
|
5
|
-
import
|
|
5
|
+
import { useTheme } from '@dr.pogodin/react-themes';
|
|
6
6
|
import { optionValueName } from "../common.js";
|
|
7
7
|
import Options, { areEqual } from "./Options/index.js";
|
|
8
8
|
const defaultTheme = {
|
|
@@ -19,7 +19,7 @@ const defaultTheme = {
|
|
|
19
19
|
"upward": "-dr-pogodin-react-utils___build-web-shared-components-selectors-CustomDropdown-theme___upward___--5Xpy"
|
|
20
20
|
};
|
|
21
21
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
22
|
-
const
|
|
22
|
+
const CustomDropdown = ({
|
|
23
23
|
filter,
|
|
24
24
|
label,
|
|
25
25
|
onChange,
|
|
@@ -27,6 +27,7 @@ const BaseCustomDropdown = ({
|
|
|
27
27
|
theme,
|
|
28
28
|
value
|
|
29
29
|
}) => {
|
|
30
|
+
const custom = useTheme('CustomDropdown', defaultTheme, theme);
|
|
30
31
|
const [active, setActive] = useState(false);
|
|
31
32
|
const dropdownRef = useRef(null);
|
|
32
33
|
const opsRef = useRef(null);
|
|
@@ -91,20 +92,20 @@ const BaseCustomDropdown = ({
|
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
|
-
let containerClassName =
|
|
95
|
-
if (active) containerClassName += ` ${
|
|
96
|
-
let opsContainerClass =
|
|
95
|
+
let containerClassName = custom.container;
|
|
96
|
+
if (active) containerClassName += ` ${custom.active}`;
|
|
97
|
+
let opsContainerClass = custom.select ?? '';
|
|
97
98
|
if (upward) {
|
|
98
|
-
containerClassName += ` ${
|
|
99
|
-
opsContainerClass += ` ${
|
|
99
|
+
containerClassName += ` ${custom.upward}`;
|
|
100
|
+
opsContainerClass += ` ${custom.upward}`;
|
|
100
101
|
}
|
|
101
102
|
return /*#__PURE__*/_jsxs("div", {
|
|
102
103
|
className: containerClassName,
|
|
103
104
|
children: [label === undefined ? null : /*#__PURE__*/_jsx("div", {
|
|
104
|
-
className:
|
|
105
|
+
className: custom.label,
|
|
105
106
|
children: label
|
|
106
107
|
}), /*#__PURE__*/_jsxs("div", {
|
|
107
|
-
className:
|
|
108
|
+
className: custom.dropdown,
|
|
108
109
|
onClick: openList,
|
|
109
110
|
onKeyDown: e => {
|
|
110
111
|
if (e.key === 'Enter') openList(e);
|
|
@@ -113,7 +114,7 @@ const BaseCustomDropdown = ({
|
|
|
113
114
|
role: "listbox",
|
|
114
115
|
tabIndex: 0,
|
|
115
116
|
children: [selected, /*#__PURE__*/_jsx("div", {
|
|
116
|
-
className:
|
|
117
|
+
className: custom.arrow
|
|
117
118
|
})]
|
|
118
119
|
}), active ? /*#__PURE__*/_jsx(Options, {
|
|
119
120
|
containerClass: opsContainerClass,
|
|
@@ -125,11 +126,11 @@ const BaseCustomDropdown = ({
|
|
|
125
126
|
setActive(false);
|
|
126
127
|
if (onChange) onChange(newValue);
|
|
127
128
|
},
|
|
128
|
-
optionClass:
|
|
129
|
+
optionClass: custom.option ?? '',
|
|
129
130
|
options: options,
|
|
130
131
|
ref: opsRef
|
|
131
132
|
}) : null]
|
|
132
133
|
});
|
|
133
134
|
};
|
|
134
|
-
export default
|
|
135
|
+
export default CustomDropdown;
|
|
135
136
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useEffect","useRef","useState","
|
|
1
|
+
{"version":3,"file":"index.js","names":["useEffect","useRef","useState","useTheme","optionValueName","Options","areEqual","defaultTheme","Fragment","_Fragment","jsx","_jsx","jsxs","_jsxs","CustomDropdown","filter","label","onChange","options","theme","value","custom","active","setActive","dropdownRef","opsRef","opsPos","setOpsPos","upward","setUpward","undefined","id","cb","anchor","current","getBoundingClientRect","opsRect","measure","fitsDown","bottom","height","window","visualViewport","fitsUp","top","up","pos","left","width","now","requestAnimationFrame","cancelAnimationFrame","openList","e","view","rect","stopPropagation","selected","children","option","iValue","iName","containerClassName","container","opsContainerClass","select","className","dropdown","onClick","onKeyDown","key","ref","role","tabIndex","arrow","containerClass","containerStyle","onCancel","newValue","optionClass"],"sources":["../../../../../../src/shared/components/selectors/CustomDropdown/index.tsx"],"sourcesContent":["import {\n type FunctionComponent,\n type ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { useTheme } from '@dr.pogodin/react-themes';\n\nimport { type PropsT, type ValueT, optionValueName } from '../common';\n\nimport Options, { type ContainerPosT, type RefT, areEqual } from './Options';\n\nimport defaultTheme from './theme.scss';\n\nconst CustomDropdown: FunctionComponent<\n PropsT<ReactNode, (value: ValueT) => void>\n> = ({\n filter,\n label,\n onChange,\n options,\n theme,\n value,\n}) => {\n const custom = useTheme('CustomDropdown', defaultTheme, theme);\n\n const [active, setActive] = useState(false);\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const opsRef = useRef<RefT>(null);\n\n const [opsPos, setOpsPos] = useState<ContainerPosT>();\n const [upward, setUpward] = useState(false);\n\n useEffect(() => {\n if (!active) return undefined;\n\n let id: number;\n const cb = () => {\n const anchor = dropdownRef.current?.getBoundingClientRect();\n const opsRect = opsRef.current?.measure();\n if (anchor && opsRect) {\n const fitsDown = anchor.bottom + opsRect.height\n < (window.visualViewport?.height ?? 0);\n const fitsUp = anchor.top - opsRect.height > 0;\n\n const up = !fitsDown && fitsUp;\n setUpward(up);\n\n const pos = up ? {\n left: anchor.left,\n top: anchor.top - opsRect.height - 1,\n width: anchor.width,\n } : {\n left: anchor.left,\n top: anchor.bottom,\n width: anchor.width,\n };\n\n setOpsPos((now) => (areEqual(now, pos) ? now : pos));\n }\n id = requestAnimationFrame(cb);\n };\n requestAnimationFrame(cb);\n\n return () => {\n cancelAnimationFrame(id);\n };\n }, [active]);\n\n const openList = (\n e: React.KeyboardEvent<HTMLDivElement> | React.MouseEvent<HTMLDivElement>,\n ) => {\n const view = window.visualViewport;\n const rect = dropdownRef.current!.getBoundingClientRect();\n setActive(true);\n\n // NOTE: This first opens the dropdown off-screen, where it is measured\n // by an effect declared above, and then positioned below, or above\n // the original dropdown element, depending where it fits best\n // (if we first open it downward, it would flick if we immediately\n // move it above, at least with the current position update via local\n // react state, and not imperatively).\n setOpsPos({\n left: view?.width ?? 0,\n top: view?.height ?? 0,\n width: rect.width,\n });\n\n e.stopPropagation();\n };\n\n let selected: React.ReactNode = <>‌</>;\n for (const option of options) {\n if (!filter || filter(option)) {\n const [iValue, iName] = optionValueName(option);\n if (iValue === value) {\n selected = iName;\n break;\n }\n }\n }\n\n let containerClassName = custom.container;\n if (active) containerClassName += ` ${custom.active}`;\n\n let opsContainerClass = custom.select ?? '';\n if (upward) {\n containerClassName += ` ${custom.upward}`;\n opsContainerClass += ` ${custom.upward}`;\n }\n\n return (\n <div className={containerClassName}>\n {label === undefined ? null\n : <div className={custom.label}>{label}</div>}\n <div\n className={custom.dropdown}\n onClick={openList}\n onKeyDown={(e) => {\n if (e.key === 'Enter') openList(e);\n }}\n ref={dropdownRef}\n role=\"listbox\"\n tabIndex={0}\n >\n {selected}\n <div className={custom.arrow} />\n </div>\n {\n active ? (\n <Options\n containerClass={opsContainerClass}\n containerStyle={opsPos}\n onCancel={() => {\n setActive(false);\n }}\n onChange={(newValue) => {\n setActive(false);\n if (onChange) onChange(newValue);\n }}\n optionClass={custom.option ?? ''}\n options={options}\n ref={opsRef}\n />\n ) : null\n }\n </div>\n );\n};\n\nexport default CustomDropdown;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -4,7 +4,7 @@ import "core-js/modules/es.iterator.constructor.js";
|
|
|
4
4
|
import "core-js/modules/es.iterator.filter.js";
|
|
5
5
|
// Implements dropdown based on the native HTML <select> element.
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import { useTheme } from '@dr.pogodin/react-themes';
|
|
8
8
|
import { optionValueName } from "../common.js";
|
|
9
9
|
const defaultTheme = {
|
|
10
10
|
"context": "-dr-pogodin-react-utils___build-web-shared-components-selectors-NativeDropdown-theme___context___WbwY1Y",
|
|
@@ -51,12 +51,13 @@ const Dropdown = ({
|
|
|
51
51
|
}) => {
|
|
52
52
|
let isValidValue = false;
|
|
53
53
|
const optionElements = [];
|
|
54
|
+
const composed = useTheme('Dropdown', defaultTheme, theme);
|
|
54
55
|
for (const option of options) {
|
|
55
56
|
if (!filter || filter(option)) {
|
|
56
57
|
const [iValue, iName] = optionValueName(option);
|
|
57
58
|
isValidValue ||= iValue === value;
|
|
58
59
|
optionElements.push(/*#__PURE__*/_jsx("option", {
|
|
59
|
-
className:
|
|
60
|
+
className: composed.option,
|
|
60
61
|
value: iValue,
|
|
61
62
|
children: iName
|
|
62
63
|
}, iValue));
|
|
@@ -68,20 +69,20 @@ const Dropdown = ({
|
|
|
68
69
|
// it from the opened dropdown; in others, e.g. Safari, the best we can do is
|
|
69
70
|
// to show it as disabled.
|
|
70
71
|
const hiddenOption = isValidValue ? null : /*#__PURE__*/_jsx("option", {
|
|
71
|
-
className:
|
|
72
|
+
className: composed.hiddenOption,
|
|
72
73
|
disabled: true,
|
|
73
74
|
value: value,
|
|
74
75
|
children: value
|
|
75
76
|
}, "__reactUtilsHiddenOption");
|
|
76
|
-
let selectClassName =
|
|
77
|
-
if (!isValidValue) selectClassName += ` ${
|
|
77
|
+
let selectClassName = composed.select;
|
|
78
|
+
if (!isValidValue) selectClassName += ` ${composed.invalid}`;
|
|
78
79
|
return /*#__PURE__*/_jsxs("div", {
|
|
79
|
-
className:
|
|
80
|
+
className: composed.container,
|
|
80
81
|
children: [label === undefined ? null : /*#__PURE__*/_jsx("div", {
|
|
81
|
-
className:
|
|
82
|
+
className: composed.label,
|
|
82
83
|
children: label
|
|
83
84
|
}), /*#__PURE__*/_jsxs("div", {
|
|
84
|
-
className:
|
|
85
|
+
className: composed.dropdown,
|
|
85
86
|
children: [/*#__PURE__*/_jsxs("select", {
|
|
86
87
|
className: selectClassName,
|
|
87
88
|
"data-testid": process.env.NODE_ENV === 'production' ? undefined : testId,
|
|
@@ -89,10 +90,10 @@ const Dropdown = ({
|
|
|
89
90
|
value: value,
|
|
90
91
|
children: [hiddenOption, optionElements]
|
|
91
92
|
}), /*#__PURE__*/_jsx("div", {
|
|
92
|
-
className:
|
|
93
|
+
className: composed.arrow
|
|
93
94
|
})]
|
|
94
95
|
})]
|
|
95
96
|
});
|
|
96
97
|
};
|
|
97
|
-
export default
|
|
98
|
+
export default Dropdown;
|
|
98
99
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["
|
|
1
|
+
{"version":3,"file":"index.js","names":["useTheme","optionValueName","defaultTheme","jsx","_jsx","jsxs","_jsxs","Dropdown","filter","label","onChange","options","testId","theme","value","isValidValue","optionElements","composed","option","iValue","iName","push","className","children","hiddenOption","disabled","selectClassName","select","invalid","container","undefined","dropdown","process","env","NODE_ENV","arrow"],"sources":["../../../../../../src/shared/components/selectors/NativeDropdown/index.tsx"],"sourcesContent":["// Implements dropdown based on the native HTML <select> element.\n\nimport type { FunctionComponent } from 'react';\n\nimport { useTheme } from '@dr.pogodin/react-themes';\n\nimport { optionValueName, type PropsT } from '../common';\n\nimport defaultTheme from './theme.scss';\n\n/**\n * Implements a themeable dropdown list. Internally it is rendered with help of\n * the standard HTML `<select>` element, thus the styling support is somewhat\n * limited.\n * @param [props] Component properties.\n * @param [props.filter] Options filter function. If provided, only\n * those elements of `options` list will be used by the dropdown, for which this\n * filter returns `true`.\n * @param [props.label] Dropdown label.\n * @param [props.onChange] Selection event handler.\n * @param [props.options=[]] Array of dropdown\n * options. For string elements the option value and name will be the same.\n * It is allowed to mix DropdownOption and string elements in the same option\n * list.\n * @param [props.theme] _Ad hoc_ theme.\n * @param [props.value] Currently selected value.\n * @param [props....]\n * [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)\n */\nconst Dropdown: FunctionComponent<PropsT<string>> = ({\n filter,\n label,\n onChange,\n options,\n testId,\n theme,\n value,\n}) => {\n let isValidValue = false;\n const optionElements = [];\n\n const composed = useTheme('Dropdown', defaultTheme, theme);\n\n for (const option of options) {\n if (!filter || filter(option)) {\n const [iValue, iName] = optionValueName(option);\n isValidValue ||= iValue === value;\n optionElements.push(\n <option className={composed.option} key={iValue} value={iValue}>\n {iName}\n </option>,\n );\n }\n }\n\n // NOTE: This element represents the current `value` when it does not match\n // any valid option. In Chrome, and some other browsers, we are able to hide\n // it from the opened dropdown; in others, e.g. Safari, the best we can do is\n // to show it as disabled.\n const hiddenOption = isValidValue ? null : (\n <option\n className={composed.hiddenOption}\n disabled\n key=\"__reactUtilsHiddenOption\"\n value={value}\n >\n {value}\n </option>\n );\n\n let selectClassName = composed.select;\n if (!isValidValue) selectClassName += ` ${composed.invalid}`;\n\n return (\n <div className={composed.container}>\n { label === undefined\n ? null : <div className={composed.label}>{label}</div> }\n <div className={composed.dropdown}>\n <select\n className={selectClassName}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n onChange={onChange}\n value={value}\n >\n {hiddenOption}\n {optionElements}\n </select>\n <div className={composed.arrow} />\n </div>\n </div>\n );\n};\n\nexport default Dropdown;\n"],"mappings":";;;;AAAA;;AAIA,SAASA,QAAQ,QAAQ,0BAA0B;AAAA,SAE1CC,eAAe;AAAA,MAAAC,YAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAIxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAlBA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAmBA,MAAMC,QAA2C,GAAGA,CAAC;EACnDC,MAAM;EACNC,KAAK;EACLC,QAAQ;EACRC,OAAO;EACPC,MAAM;EACNC,KAAK;EACLC;AACF,CAAC,KAAK;EACJ,IAAIC,YAAY,GAAG,KAAK;EACxB,MAAMC,cAAc,GAAG,EAAE;EAEzB,MAAMC,QAAQ,GAAGjB,QAAQ,CAAC,UAAU,EAAEE,YAAY,EAAEW,KAAK,CAAC;EAE1D,KAAK,MAAMK,MAAM,IAAIP,OAAO,EAAE;IAC5B,IAAI,CAACH,MAAM,IAAIA,MAAM,CAACU,MAAM,CAAC,EAAE;MAC7B,MAAM,CAACC,MAAM,EAAEC,KAAK,CAAC,GAAGnB,eAAe,CAACiB,MAAM,CAAC;MAC/CH,YAAY,KAAKI,MAAM,KAAKL,KAAK;MACjCE,cAAc,CAACK,IAAI,cACjBjB,IAAA;QAAQkB,SAAS,EAAEL,QAAQ,CAACC,MAAO;QAAcJ,KAAK,EAAEK,MAAO;QAAAI,QAAA,EAC5DH;MAAK,GADiCD,MAEjC,CACV,CAAC;IACH;EACF;;EAEA;EACA;EACA;EACA;EACA,MAAMK,YAAY,GAAGT,YAAY,GAAG,IAAI,gBACtCX,IAAA;IACEkB,SAAS,EAAEL,QAAQ,CAACO,YAAa;IACjCC,QAAQ;IAERX,KAAK,EAAEA,KAAM;IAAAS,QAAA,EAEZT;EAAK,GAHF,0BAIE,CACT;EAED,IAAIY,eAAe,GAAGT,QAAQ,CAACU,MAAM;EACrC,IAAI,CAACZ,YAAY,EAAEW,eAAe,IAAI,IAAIT,QAAQ,CAACW,OAAO,EAAE;EAE5D,oBACEtB,KAAA;IAAKgB,SAAS,EAAEL,QAAQ,CAACY,SAAU;IAAAN,QAAA,GAC/Bd,KAAK,KAAKqB,SAAS,GACjB,IAAI,gBAAG1B,IAAA;MAAKkB,SAAS,EAAEL,QAAQ,CAACR,KAAM;MAAAc,QAAA,EAAEd;IAAK,CAAM,CAAC,eACxDH,KAAA;MAAKgB,SAAS,EAAEL,QAAQ,CAACc,QAAS;MAAAR,QAAA,gBAChCjB,KAAA;QACEgB,SAAS,EAAEI,eAAgB;QAC3B,eAAaM,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,GAAGJ,SAAS,GAAGlB,MAAO;QACxEF,QAAQ,EAAEA,QAAS;QACnBI,KAAK,EAAEA,KAAM;QAAAS,QAAA,GAEZC,YAAY,EACZR,cAAc;MAAA,CACT,CAAC,eACTZ,IAAA;QAAKkB,SAAS,EAAEL,QAAQ,CAACkB;MAAM,CAAE,CAAC;IAAA,CAC/B,CAAC;EAAA,CACH,CAAC;AAEV,CAAC;AAED,eAAe5B,QAAQ","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "core-js/modules/es.array.push.js";
|
|
2
|
-
import
|
|
2
|
+
import { useTheme } from '@dr.pogodin/react-themes';
|
|
3
3
|
import { optionValueName } from "../common.js";
|
|
4
4
|
const defaultTheme = {
|
|
5
5
|
"context": "-dr-pogodin-react-utils___build-web-shared-components-selectors-Switch-theme___context___akD3dQ",
|
|
@@ -11,20 +11,21 @@ const defaultTheme = {
|
|
|
11
11
|
"options": "-dr-pogodin-react-utils___build-web-shared-components-selectors-Switch-theme___options___9-eOZo"
|
|
12
12
|
};
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
const
|
|
14
|
+
export const Switch = ({
|
|
15
15
|
label,
|
|
16
16
|
onChange,
|
|
17
17
|
options,
|
|
18
18
|
theme,
|
|
19
19
|
value
|
|
20
20
|
}) => {
|
|
21
|
-
|
|
21
|
+
const composed = useTheme('Switch', defaultTheme, theme);
|
|
22
|
+
if (!options || !composed.option) throw Error('Internal error');
|
|
22
23
|
const optionNodes = [];
|
|
23
24
|
for (const option of options) {
|
|
24
25
|
const [iValue, iName] = optionValueName(option);
|
|
25
|
-
let className =
|
|
26
|
+
let className = composed.option;
|
|
26
27
|
let onPress;
|
|
27
|
-
if (iValue === value) className += ` ${
|
|
28
|
+
if (iValue === value) className += ` ${composed.selected}`;else if (onChange) {
|
|
28
29
|
onPress = () => {
|
|
29
30
|
onChange(iValue);
|
|
30
31
|
};
|
|
@@ -44,15 +45,14 @@ const BaseSwitch = ({
|
|
|
44
45
|
}, iValue));
|
|
45
46
|
}
|
|
46
47
|
return /*#__PURE__*/_jsxs("div", {
|
|
47
|
-
className:
|
|
48
|
+
className: composed.container,
|
|
48
49
|
children: [label ? /*#__PURE__*/_jsx("div", {
|
|
49
|
-
className:
|
|
50
|
+
className: composed.label,
|
|
50
51
|
children: label
|
|
51
52
|
}) : null, /*#__PURE__*/_jsx("div", {
|
|
52
|
-
className:
|
|
53
|
+
className: composed.options,
|
|
53
54
|
children: optionNodes
|
|
54
55
|
})]
|
|
55
56
|
});
|
|
56
57
|
};
|
|
57
|
-
export default /* #__PURE__ */themed(BaseSwitch, 'Switch', defaultTheme);
|
|
58
58
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["
|
|
1
|
+
{"version":3,"file":"index.js","names":["useTheme","optionValueName","defaultTheme","jsx","_jsx","jsxs","_jsxs","Switch","label","onChange","options","theme","value","composed","option","Error","optionNodes","iValue","iName","className","onPress","selected","push","onClick","onKeyDown","e","key","role","tabIndex","children","container"],"sources":["../../../../../../src/shared/components/selectors/Switch/index.tsx"],"sourcesContent":["import type { FunctionComponent, ReactNode } from 'react';\n\nimport { type Theme, useTheme } from '@dr.pogodin/react-themes';\n\nimport {\n type OptionsT,\n type ValueT,\n optionValueName,\n} from '../common';\n\nimport defaultTheme from './theme.scss';\n\ntype ThemeT = Theme<'container' | 'label' | 'option' | 'options' | 'selected'>;\n\ntype PropsT = {\n label?: ReactNode;\n onChange?: (value: ValueT) => void;\n options?: Readonly<OptionsT<ReactNode>>;\n theme?: ThemeT;\n value?: ValueT;\n};\n\nexport const Switch: FunctionComponent<PropsT> = ({\n label,\n onChange,\n options,\n theme,\n value,\n}) => {\n const composed = useTheme('Switch', defaultTheme, theme);\n\n if (!options || !composed.option) throw Error('Internal error');\n\n const optionNodes: React.ReactNode[] = [];\n for (const option of options) {\n const [iValue, iName] = optionValueName(option);\n\n let className: string = composed.option;\n let onPress: (() => void) | undefined;\n if (iValue === value) className += ` ${composed.selected}`;\n else if (onChange) {\n onPress = () => {\n onChange(iValue);\n };\n }\n\n optionNodes.push(\n onPress\n ? (\n <div\n className={className}\n key={iValue}\n onClick={onPress}\n onKeyDown={(e) => {\n if (e.key === 'Enter') onPress();\n }}\n role=\"button\"\n tabIndex={0}\n >\n {iName}\n </div>\n )\n : <div className={className} key={iValue}>{iName}</div>,\n );\n }\n\n return (\n <div className={composed.container}>\n {label ? <div className={composed.label}>{label}</div> : null}\n\n <div className={composed.options}>\n {optionNodes}\n </div>\n </div>\n );\n};\n"],"mappings":";AAEA,SAAqBA,QAAQ,QAAQ,0BAA0B;AAAA,SAK7DC,eAAe;AAAA,MAAAC,YAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAGuB,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAYxC,OAAO,MAAMC,MAAiC,GAAGA,CAAC;EAChDC,KAAK;EACLC,QAAQ;EACRC,OAAO;EACPC,KAAK;EACLC;AACF,CAAC,KAAK;EACJ,MAAMC,QAAQ,GAAGb,QAAQ,CAAC,QAAQ,EAAEE,YAAY,EAAES,KAAK,CAAC;EAExD,IAAI,CAACD,OAAO,IAAI,CAACG,QAAQ,CAACC,MAAM,EAAE,MAAMC,KAAK,CAAC,gBAAgB,CAAC;EAE/D,MAAMC,WAA8B,GAAG,EAAE;EACzC,KAAK,MAAMF,MAAM,IAAIJ,OAAO,EAAE;IAC5B,MAAM,CAACO,MAAM,EAAEC,KAAK,CAAC,GAAGjB,eAAe,CAACa,MAAM,CAAC;IAE/C,IAAIK,SAAiB,GAAGN,QAAQ,CAACC,MAAM;IACvC,IAAIM,OAAiC;IACrC,IAAIH,MAAM,KAAKL,KAAK,EAAEO,SAAS,IAAI,IAAIN,QAAQ,CAACQ,QAAQ,EAAE,CAAC,KACtD,IAAIZ,QAAQ,EAAE;MACjBW,OAAO,GAAGA,CAAA,KAAM;QACdX,QAAQ,CAACQ,MAAM,CAAC;MAClB,CAAC;IACH;IAEAD,WAAW,CAACM,IAAI,CACdF,OAAO,gBAEHhB,IAAA;MACEe,SAAS,EAAEA,SAAU;MAErBI,OAAO,EAAEH,OAAQ;MACjBI,SAAS,EAAGC,CAAC,IAAK;QAChB,IAAIA,CAAC,CAACC,GAAG,KAAK,OAAO,EAAEN,OAAO,CAAC,CAAC;MAClC,CAAE;MACFO,IAAI,EAAC,QAAQ;MACbC,QAAQ,EAAE,CAAE;MAAAC,QAAA,EAEXX;IAAK,GARDD,MASF,CAAC,gBAENb,IAAA;MAAKe,SAAS,EAAEA,SAAU;MAAAU,QAAA,EAAeX;IAAK,GAAdD,MAAoB,CAC1D,CAAC;EACH;EAEA,oBACEX,KAAA;IAAKa,SAAS,EAAEN,QAAQ,CAACiB,SAAU;IAAAD,QAAA,GAChCrB,KAAK,gBAAGJ,IAAA;MAAKe,SAAS,EAAEN,QAAQ,CAACL,KAAM;MAAAqB,QAAA,EAAErB;IAAK,CAAM,CAAC,GAAG,IAAI,eAE7DJ,IAAA;MAAKe,SAAS,EAAEN,QAAQ,CAACH,OAAQ;MAAAmB,QAAA,EAC9Bb;IAAW,CACT,CAAC;EAAA,CACH,CAAC;AAEV,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":["isValue","x","type","optionValueName","option","value","name"],"sources":["../../../../../src/shared/components/selectors/common.ts"],"sourcesContent":["// The stuff common between different dropdown implementations.\n\nimport type { Theme } from '@dr.pogodin/react-themes';\n\
|
|
1
|
+
{"version":3,"file":"common.js","names":["isValue","x","type","optionValueName","option","value","name"],"sources":["../../../../../src/shared/components/selectors/common.ts"],"sourcesContent":["// The stuff common between different dropdown implementations.\n\nimport type { Theme } from '@dr.pogodin/react-themes';\n\nexport type ThemeT = Theme<\n | 'active'\n | 'arrow'\n | 'container'\n | 'dropdown'\n | 'hiddenOption'\n | 'label'\n | 'option'\n | 'select'\n\n // TODO: This is currently only valid for (native) <Dropdown>,\n // other kinds of selectors should be evaluated, and aligned with this\n // feature, if appropriate.\n | 'invalid'\n\n // TODO: This is only valid for <CustomDropdown>, thus we need to re-factor it\n // into a separate theme spec for that component.\n | 'upward'\n>;\n\nexport type ValueT = number | string;\n\nexport type OptionT<NameT> = {\n name?: NameT | null;\n value: ValueT;\n};\n\nexport type OptionsT<NameT> = Readonly<Array<OptionT<NameT> | ValueT>>;\n\nexport type PropsT<\n NameT,\n OnChangeT = React.ChangeEventHandler<HTMLSelectElement>,\n> = {\n filter?: (item: OptionT<NameT> | ValueT) => boolean;\n label?: React.ReactNode;\n onChange?: OnChangeT;\n options: Readonly<OptionsT<NameT>>;\n testId?: string;\n theme: ThemeT;\n value?: ValueT;\n};\n\nfunction isValue<T>(x: OptionT<T> | ValueT): x is ValueT {\n const type = typeof x;\n return type === 'number' || type === 'string';\n}\n\n/** Returns option value and name as a tuple. */\nexport function optionValueName<NameT>(\n option: OptionT<NameT> | ValueT,\n): [ValueT, NameT | ValueT] {\n return isValue(option)\n ? [option, option]\n : [option.value, option.name ?? option.value];\n}\n"],"mappings":"AAAA;;AA8CA,SAASA,OAAOA,CAAIC,CAAsB,EAAe;EACvD,MAAMC,IAAI,GAAG,OAAOD,CAAC;EACrB,OAAOC,IAAI,KAAK,QAAQ,IAAIA,IAAI,KAAK,QAAQ;AAC/C;;AAEA;AACA,OAAO,SAASC,eAAeA,CAC7BC,MAA+B,EACL;EAC1B,OAAOJ,OAAO,CAACI,MAAM,CAAC,GAClB,CAACA,MAAM,EAAEA,MAAM,CAAC,GAChB,CAACA,MAAM,CAACC,KAAK,EAAED,MAAM,CAACE,IAAI,IAAIF,MAAM,CAACC,KAAK,CAAC;AACjD","ignoreList":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as CustomDropdown } from "./CustomDropdown/index.js";
|
|
2
2
|
export { default as Dropdown } from "./NativeDropdown/index.js";
|
|
3
|
-
export {
|
|
3
|
+
export { Switch } from "./Switch/index.js";
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["default","CustomDropdown","Dropdown","Switch"],"sources":["../../../../../src/shared/components/selectors/index.ts"],"sourcesContent":["export { default as CustomDropdown } from './CustomDropdown';\nexport { default as Dropdown } from './NativeDropdown';\nexport {
|
|
1
|
+
{"version":3,"file":"index.js","names":["default","CustomDropdown","Dropdown","Switch"],"sources":["../../../../../src/shared/components/selectors/index.ts"],"sourcesContent":["export { default as CustomDropdown } from './CustomDropdown';\nexport { default as Dropdown } from './NativeDropdown';\nexport { Switch } from './Switch';\n\nexport type { OptionT, OptionsT } from './common';\n"],"mappings":"SAASA,OAAO,IAAIC,cAAc;AAAA,SACzBD,OAAO,IAAIE,QAAQ;AAAA,SACnBC,MAAM","ignoreList":[]}
|