@dr.pogodin/react-utils 1.47.0-alpha.7 → 1.47.0-alpha.9
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/client/index.js +1 -1
- package/build/development/client/index.js.map +1 -1
- package/build/development/index.js +1 -11
- package/build/development/index.js.map +1 -1
- package/build/development/server/index.js +3 -6
- package/build/development/server/index.js.map +1 -1
- package/build/development/server/utils/index.js +1 -1
- package/build/development/server/utils/index.js.map +1 -1
- package/build/development/shared/components/Button/index.js +1 -1
- package/build/development/shared/components/Button/index.js.map +1 -1
- package/build/development/shared/components/Checkbox/index.js +1 -1
- package/build/development/shared/components/Checkbox/index.js.map +1 -1
- package/build/development/shared/components/Input/index.js +1 -1
- package/build/development/shared/components/Input/index.js.map +1 -1
- package/build/development/shared/components/Modal/index.js +1 -1
- package/build/development/shared/components/Modal/index.js.map +1 -1
- package/build/development/shared/components/PageLayout/index.js +1 -1
- package/build/development/shared/components/PageLayout/index.js.map +1 -1
- package/build/development/shared/components/TextArea/index.js +1 -1
- package/build/development/shared/components/TextArea/index.js.map +1 -1
- package/build/development/shared/components/Throbber/index.js +1 -1
- package/build/development/shared/components/Throbber/index.js.map +1 -1
- package/build/development/shared/components/WithTooltip/index.js +1 -1
- package/build/development/shared/components/WithTooltip/index.js.map +1 -1
- package/build/development/shared/components/YouTubeVideo/index.js +1 -1
- package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/index.js +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/NativeDropdown/index.js +1 -1
- package/build/development/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/Switch/index.js +1 -1
- package/build/development/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/production/client/index.js +1 -1
- package/build/production/client/index.js.map +1 -1
- package/build/production/index.js +2 -6
- package/build/production/index.js.map +1 -1
- package/build/production/server/index.js +3 -3
- package/build/production/server/index.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 +1 -1
- 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 +1 -1
- package/build/production/shared/components/Input/index.js.map +1 -1
- package/build/production/shared/components/Modal/index.js +1 -1
- package/build/production/shared/components/Modal/index.js.map +1 -1
- package/build/production/shared/components/PageLayout/index.js +1 -1
- package/build/production/shared/components/PageLayout/index.js.map +1 -1
- package/build/production/shared/components/TextArea/index.js +1 -1
- package/build/production/shared/components/TextArea/index.js.map +1 -1
- package/build/production/shared/components/Throbber/index.js +1 -1
- package/build/production/shared/components/Throbber/index.js.map +1 -1
- package/build/production/shared/components/WithTooltip/index.js +1 -1
- package/build/production/shared/components/WithTooltip/index.js.map +1 -1
- package/build/production/shared/components/YouTubeVideo/index.js +1 -1
- package/build/production/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/index.js +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/production/shared/components/selectors/NativeDropdown/index.js +1 -1
- 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/types-code/client/index.d.ts +1 -1
- package/build/types-code/index.d.ts +0 -6
- package/build/types-code/server/index.d.ts +4 -9
- package/build/types-code/server/utils/index.d.ts +1 -1
- package/build/web/client/index.js +1 -1
- package/build/web/client/index.js.map +1 -1
- package/build/web/index.js +0 -12
- package/build/web/index.js.map +1 -1
- package/build/web/server/index.js +3 -6
- package/build/web/server/index.js.map +1 -1
- package/build/web/server/utils/index.js +1 -1
- package/build/web/server/utils/index.js.map +1 -1
- package/build/web/shared/components/Button/index.js +1 -1
- package/build/web/shared/components/Button/index.js.map +1 -1
- package/build/web/shared/components/Checkbox/index.js +1 -1
- package/build/web/shared/components/Checkbox/index.js.map +1 -1
- package/build/web/shared/components/Input/index.js +1 -1
- package/build/web/shared/components/Input/index.js.map +1 -1
- package/build/web/shared/components/Modal/index.js +1 -1
- package/build/web/shared/components/Modal/index.js.map +1 -1
- package/build/web/shared/components/PageLayout/index.js +1 -1
- package/build/web/shared/components/PageLayout/index.js.map +1 -1
- package/build/web/shared/components/TextArea/index.js +1 -1
- package/build/web/shared/components/TextArea/index.js.map +1 -1
- package/build/web/shared/components/Throbber/index.js +1 -1
- package/build/web/shared/components/Throbber/index.js.map +1 -1
- package/build/web/shared/components/WithTooltip/index.js +1 -1
- package/build/web/shared/components/WithTooltip/index.js.map +1 -1
- package/build/web/shared/components/YouTubeVideo/index.js +1 -1
- package/build/web/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/web/shared/components/selectors/CustomDropdown/index.js +1 -1
- package/build/web/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/web/shared/components/selectors/NativeDropdown/index.js +1 -1
- package/build/web/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/web/shared/components/selectors/Switch/index.js +1 -1
- package/build/web/shared/components/selectors/Switch/index.js.map +1 -1
- package/package.json +17 -6
- package/src/client/getInj.ts +0 -71
- package/src/client/index.tsx +0 -45
- package/src/client/init.ts +0 -52
- package/src/index.ts +0 -75
- package/src/server/Cache.ts +0 -61
- package/src/server/index.ts +0 -243
- package/src/server/renderer.tsx +0 -635
- package/src/server/server.ts +0 -330
- package/src/server/utils/errors.ts +0 -122
- package/src/server/utils/index.ts +0 -3
- package/src/shared/components/Button/index.tsx +0 -130
- package/src/shared/components/Button/style.scss +0 -54
- package/src/shared/components/Checkbox/index.tsx +0 -53
- package/src/shared/components/Checkbox/theme.scss +0 -63
- package/src/shared/components/GenericLink/index.tsx +0 -141
- package/src/shared/components/GenericLink/style.scss +0 -3
- package/src/shared/components/Input/index.tsx +0 -96
- package/src/shared/components/Input/theme.scss +0 -52
- package/src/shared/components/Link.tsx +0 -25
- package/src/shared/components/Modal/base-theme.scss +0 -38
- package/src/shared/components/Modal/index.tsx +0 -177
- package/src/shared/components/Modal/styles.scss +0 -3
- package/src/shared/components/NavLink.tsx +0 -18
- package/src/shared/components/PageLayout/base-theme.scss +0 -30
- package/src/shared/components/PageLayout/index.tsx +0 -51
- package/src/shared/components/TextArea/index.tsx +0 -139
- package/src/shared/components/TextArea/style.scss +0 -68
- package/src/shared/components/Throbber/index.tsx +0 -28
- package/src/shared/components/Throbber/theme.scss +0 -26
- package/src/shared/components/WithTooltip/Tooltip.tsx +0 -274
- package/src/shared/components/WithTooltip/default-theme.scss +0 -36
- package/src/shared/components/WithTooltip/index.tsx +0 -186
- package/src/shared/components/YouTubeVideo/base.scss +0 -15
- package/src/shared/components/YouTubeVideo/index.tsx +0 -73
- package/src/shared/components/YouTubeVideo/throbber.scss +0 -11
- package/src/shared/components/index.ts +0 -20
- package/src/shared/components/selectors/CustomDropdown/Options/index.tsx +0 -124
- package/src/shared/components/selectors/CustomDropdown/Options/style.scss +0 -6
- package/src/shared/components/selectors/CustomDropdown/index.tsx +0 -146
- package/src/shared/components/selectors/CustomDropdown/theme.scss +0 -118
- package/src/shared/components/selectors/NativeDropdown/index.tsx +0 -90
- package/src/shared/components/selectors/NativeDropdown/theme.scss +0 -81
- package/src/shared/components/selectors/Switch/index.tsx +0 -74
- package/src/shared/components/selectors/Switch/theme.scss +0 -39
- package/src/shared/components/selectors/common.ts +0 -57
- package/src/shared/components/selectors/index.ts +0 -8
- package/src/shared/utils/config.ts +0 -59
- package/src/shared/utils/globalState.ts +0 -44
- package/src/shared/utils/index.ts +0 -45
- package/src/shared/utils/isomorphy/buildInfo.ts +0 -50
- package/src/shared/utils/isomorphy/environment-check.ts +0 -18
- package/src/shared/utils/isomorphy/index.ts +0 -36
- package/src/shared/utils/jest/E2eSsrEnv.ts +0 -304
- package/src/shared/utils/jest/global.ts +0 -17
- package/src/shared/utils/jest/index.ts +0 -215
- package/src/shared/utils/splitComponent.tsx +0 -284
- package/src/shared/utils/time.ts +0 -101
- package/src/shared/utils/webpack.ts +0 -80
- package/src/styles/_global/reset.css +0 -52
- package/src/styles/_mixins/fonts.scss +0 -40
- package/src/styles/_mixins/media.scss +0 -150
- package/src/styles/_mixins/typography.scss +0 -83
- package/src/styles/global.scss +0 -11
- package/src/styles/mixins.scss +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useEffect","useRef","useState","themed","optionValueName","Options","areEqual","defaultTheme","Fragment","_Fragment","jsx","_jsx","jsxs","_jsxs","BaseCustomDropdown","filter","label","onChange","options","theme","value","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 { useEffect, useRef, useState } from 'react';\n\nimport themed 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 BaseCustomDropdown: React.FunctionComponent<\n PropsT<React.ReactNode, (value: ValueT) => void>\n> = ({\n filter,\n label,\n onChange,\n options,\n theme,\n value,\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 = theme.container;\n if (active) containerClassName += ` ${theme.active}`;\n\n let opsContainerClass = theme.select ?? '';\n if (upward) {\n containerClassName += ` ${theme.upward}`;\n opsContainerClass += ` ${theme.upward}`;\n }\n\n return (\n <div className={containerClassName}>\n {label === undefined ? null\n : <div className={theme.label}>{label}</div>}\n <div\n className={theme.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={theme.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={theme.option ?? ''}\n options={options}\n ref={opsRef}\n />\n ) : null\n }\n </div>\n );\n};\n\nexport default themed(BaseCustomDropdown, 'CustomDropdown', defaultTheme);\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","names":["useEffect","useRef","useState","themed","optionValueName","Options","areEqual","defaultTheme","Fragment","_Fragment","jsx","_jsx","jsxs","_jsxs","BaseCustomDropdown","filter","label","onChange","options","theme","value","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 { useEffect, useRef, useState } from 'react';\n\nimport themed 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 BaseCustomDropdown: React.FunctionComponent<\n PropsT<React.ReactNode, (value: ValueT) => void>\n> = ({\n filter,\n label,\n onChange,\n options,\n theme,\n value,\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 = theme.container;\n if (active) containerClassName += ` ${theme.active}`;\n\n let opsContainerClass = theme.select ?? '';\n if (upward) {\n containerClassName += ` ${theme.upward}`;\n opsContainerClass += ` ${theme.upward}`;\n }\n\n return (\n <div className={containerClassName}>\n {label === undefined ? null\n : <div className={theme.label}>{label}</div>}\n <div\n className={theme.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={theme.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={theme.option ?? ''}\n options={options}\n ref={opsRef}\n />\n ) : null\n }\n </div>\n );\n};\n\nexport default /* #__PURE__ */ themed(BaseCustomDropdown, 'CustomDropdown', defaultTheme);\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["themed","optionValueName","defaultTheme","jsx","_jsx","jsxs","_jsxs","Dropdown","filter","label","onChange","options","testId","theme","value","isValidValue","optionElements","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 themed from '@dr.pogodin/react-themes';\n\nimport { type PropsT, optionValueName } 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: React.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 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={theme.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={theme.hiddenOption}\n disabled\n key=\"__reactUtilsHiddenOption\"\n value={value}\n >\n {value}\n </option>\n );\n\n let selectClassName = theme.select;\n if (!isValidValue) selectClassName += ` ${theme.invalid}`;\n\n return (\n <div className={theme.container}>\n { label === undefined\n ? null : <div className={theme.label}>{label}</div> }\n <div className={theme.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={theme.arrow} />\n </div>\n </div>\n );\n};\n\nexport default themed(Dropdown, 'Dropdown', defaultTheme);\n"],"mappings":";;;;;;AAAA;;AAEA,OAAOA,MAAM,MAAM,0BAA0B;AAAA,SAEvBC,eAAe;AAAA,MAAAC,YAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAIrC;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,QAAiD,GAAGA,CAAC;EACzDC,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,KAAK,MAAMC,MAAM,IAAIN,OAAO,EAAE;IAC5B,IAAI,CAACH,MAAM,IAAIA,MAAM,CAACS,MAAM,CAAC,EAAE;MAC7B,MAAM,CAACC,MAAM,EAAEC,KAAK,CAAC,GAAGlB,eAAe,CAACgB,MAAM,CAAC;MAC/CF,YAAY,KAAKG,MAAM,KAAKJ,KAAK;MACjCE,cAAc,CAACI,IAAI,cACjBhB,IAAA;QAAQiB,SAAS,EAAER,KAAK,CAACI,MAAO;QAAcH,KAAK,EAAEI,MAAO;QAAAI,QAAA,EACzDH;MAAK,GAD8BD,MAE9B,CACV,CAAC;IACH;EACF;;EAEA;EACA;EACA;EACA;EACA,MAAMK,YAAY,GAAGR,YAAY,GAAG,IAAI,gBACtCX,IAAA;IACEiB,SAAS,EAAER,KAAK,CAACU,YAAa;IAC9BC,QAAQ;IAERV,KAAK,EAAEA,KAAM;IAAAQ,QAAA,EAEZR;EAAK,GAHF,0BAIE,CACT;EAED,IAAIW,eAAe,GAAGZ,KAAK,CAACa,MAAM;EAClC,IAAI,CAACX,YAAY,EAAEU,eAAe,IAAI,IAAIZ,KAAK,CAACc,OAAO,EAAE;EAEzD,oBACErB,KAAA;IAAKe,SAAS,EAAER,KAAK,CAACe,SAAU;IAAAN,QAAA,GAC5Bb,KAAK,KAAKoB,SAAS,GACjB,IAAI,gBAAGzB,IAAA;MAAKiB,SAAS,EAAER,KAAK,CAACJ,KAAM;MAAAa,QAAA,EAAEb;IAAK,CAAM,CAAC,eACrDH,KAAA;MAAKe,SAAS,EAAER,KAAK,CAACiB,QAAS;MAAAR,QAAA,gBAC7BhB,KAAA;QACEe,SAAS,EAAEI,eAAgB;QAC3B,eAAaM,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,GAAGJ,SAAS,GAAGjB,MAAO;QACxEF,QAAQ,EAAEA,QAAS;QACnBI,KAAK,EAAEA,KAAM;QAAAQ,QAAA,GAEZC,YAAY,EACZP,cAAc;MAAA,CACT,CAAC,eACTZ,IAAA;QAAKiB,SAAS,EAAER,KAAK,CAACqB;MAAM,CAAE,CAAC;IAAA,CAC5B,CAAC;EAAA,CACH,CAAC;AAEV,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"index.js","names":["themed","optionValueName","defaultTheme","jsx","_jsx","jsxs","_jsxs","Dropdown","filter","label","onChange","options","testId","theme","value","isValidValue","optionElements","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 themed from '@dr.pogodin/react-themes';\n\nimport { type PropsT, optionValueName } 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: React.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 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={theme.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={theme.hiddenOption}\n disabled\n key=\"__reactUtilsHiddenOption\"\n value={value}\n >\n {value}\n </option>\n );\n\n let selectClassName = theme.select;\n if (!isValidValue) selectClassName += ` ${theme.invalid}`;\n\n return (\n <div className={theme.container}>\n { label === undefined\n ? null : <div className={theme.label}>{label}</div> }\n <div className={theme.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={theme.arrow} />\n </div>\n </div>\n );\n};\n\nexport default /* #__PURE__ */ themed(Dropdown, 'Dropdown', defaultTheme);\n"],"mappings":";;;;;;AAAA;;AAEA,OAAOA,MAAM,MAAM,0BAA0B;AAAA,SAEvBC,eAAe;AAAA,MAAAC,YAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAIrC;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,QAAiD,GAAGA,CAAC;EACzDC,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,KAAK,MAAMC,MAAM,IAAIN,OAAO,EAAE;IAC5B,IAAI,CAACH,MAAM,IAAIA,MAAM,CAACS,MAAM,CAAC,EAAE;MAC7B,MAAM,CAACC,MAAM,EAAEC,KAAK,CAAC,GAAGlB,eAAe,CAACgB,MAAM,CAAC;MAC/CF,YAAY,KAAKG,MAAM,KAAKJ,KAAK;MACjCE,cAAc,CAACI,IAAI,cACjBhB,IAAA;QAAQiB,SAAS,EAAER,KAAK,CAACI,MAAO;QAAcH,KAAK,EAAEI,MAAO;QAAAI,QAAA,EACzDH;MAAK,GAD8BD,MAE9B,CACV,CAAC;IACH;EACF;;EAEA;EACA;EACA;EACA;EACA,MAAMK,YAAY,GAAGR,YAAY,GAAG,IAAI,gBACtCX,IAAA;IACEiB,SAAS,EAAER,KAAK,CAACU,YAAa;IAC9BC,QAAQ;IAERV,KAAK,EAAEA,KAAM;IAAAQ,QAAA,EAEZR;EAAK,GAHF,0BAIE,CACT;EAED,IAAIW,eAAe,GAAGZ,KAAK,CAACa,MAAM;EAClC,IAAI,CAACX,YAAY,EAAEU,eAAe,IAAI,IAAIZ,KAAK,CAACc,OAAO,EAAE;EAEzD,oBACErB,KAAA;IAAKe,SAAS,EAAER,KAAK,CAACe,SAAU;IAAAN,QAAA,GAC5Bb,KAAK,KAAKoB,SAAS,GACjB,IAAI,gBAAGzB,IAAA;MAAKiB,SAAS,EAAER,KAAK,CAACJ,KAAM;MAAAa,QAAA,EAAEb;IAAK,CAAM,CAAC,eACrDH,KAAA;MAAKe,SAAS,EAAER,KAAK,CAACiB,QAAS;MAAAR,QAAA,gBAC7BhB,KAAA;QACEe,SAAS,EAAEI,eAAgB;QAC3B,eAAaM,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,GAAGJ,SAAS,GAAGjB,MAAO;QACxEF,QAAQ,EAAEA,QAAS;QACnBI,KAAK,EAAEA,KAAM;QAAAQ,QAAA,GAEZC,YAAY,EACZP,cAAc;MAAA,CACT,CAAC,eACTZ,IAAA;QAAKiB,SAAS,EAAER,KAAK,CAACqB;MAAM,CAAE,CAAC;IAAA,CAC5B,CAAC;EAAA,CACH,CAAC;AAEV,CAAC;AAED,eAAe,eAAgBlC,MAAM,CAACO,QAAQ,EAAE,UAAU,EAAEL,YAAY,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["themed","optionValueName","defaultTheme","jsx","_jsx","jsxs","_jsxs","BaseSwitch","label","onChange","options","theme","value","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 themed, { type Theme } 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 ThemeKeyT = 'container' | 'label' | 'option' | 'options' | 'selected';\n\ntype PropsT = {\n label?: React.ReactNode;\n onChange?: (value: ValueT) => void;\n options?: Readonly<OptionsT<React.ReactNode>>;\n theme: Theme<ThemeKeyT>;\n value?: ValueT;\n};\n\nconst BaseSwitch: React.FunctionComponent<PropsT> = ({\n label,\n onChange,\n options,\n theme,\n value,\n}) => {\n if (!options || !theme.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 = theme.option;\n let onPress: (() => void) | undefined;\n if (iValue === value) className += ` ${theme.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={theme.container}>\n {label ? <div className={theme.label}>{label}</div> : null}\n\n <div className={theme.options}>\n {optionNodes}\n </div>\n </div>\n );\n};\n\nexport default themed(BaseSwitch, 'Switch', defaultTheme);\n"],"mappings":";;AAAA,OAAOA,MAAM,MAAsB,0BAA0B;AAAA,SAK3DC,eAAe;AAAA,MAAAC,YAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAGuB,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAYxC,MAAMC,UAA2C,GAAGA,CAAC;EACnDC,KAAK;EACLC,QAAQ;EACRC,OAAO;EACPC,KAAK;EACLC;AACF,CAAC,KAAK;EACJ,IAAI,CAACF,OAAO,IAAI,CAACC,KAAK,CAACE,MAAM,EAAE,MAAMC,KAAK,CAAC,gBAAgB,CAAC;EAE5D,MAAMC,WAA8B,GAAG,EAAE;EACzC,KAAK,MAAMF,MAAM,IAAIH,OAAO,EAAE;IAC5B,MAAM,CAACM,MAAM,EAAEC,KAAK,CAAC,GAAGhB,eAAe,CAACY,MAAM,CAAC;IAE/C,IAAIK,SAAiB,GAAGP,KAAK,CAACE,MAAM;IACpC,IAAIM,OAAiC;IACrC,IAAIH,MAAM,KAAKJ,KAAK,EAAEM,SAAS,IAAI,IAAIP,KAAK,CAACS,QAAQ,EAAE,CAAC,KACnD,IAAIX,QAAQ,EAAE;MACjBU,OAAO,GAAGA,CAAA,KAAM;QACdV,QAAQ,CAACO,MAAM,CAAC;MAClB,CAAC;IACH;IAEAD,WAAW,CAACM,IAAI,CACdF,OAAO,gBAEHf,IAAA;MACEc,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,gBAENZ,IAAA;MAAKc,SAAS,EAAEA,SAAU;MAAAU,QAAA,EAAeX;IAAK,GAAdD,MAAoB,CAC1D,CAAC;EACH;EAEA,oBACEV,KAAA;IAAKY,SAAS,EAAEP,KAAK,CAACkB,SAAU;IAAAD,QAAA,GAC7BpB,KAAK,gBAAGJ,IAAA;MAAKc,SAAS,EAAEP,KAAK,CAACH,KAAM;MAAAoB,QAAA,EAAEpB;IAAK,CAAM,CAAC,GAAG,IAAI,eAE1DJ,IAAA;MAAKc,SAAS,EAAEP,KAAK,CAACD,OAAQ;MAAAkB,QAAA,EAC3Bb;IAAW,CACT,CAAC;EAAA,CACH,CAAC;AAEV,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"index.js","names":["themed","optionValueName","defaultTheme","jsx","_jsx","jsxs","_jsxs","BaseSwitch","label","onChange","options","theme","value","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 themed, { type Theme } 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 ThemeKeyT = 'container' | 'label' | 'option' | 'options' | 'selected';\n\ntype PropsT = {\n label?: React.ReactNode;\n onChange?: (value: ValueT) => void;\n options?: Readonly<OptionsT<React.ReactNode>>;\n theme: Theme<ThemeKeyT>;\n value?: ValueT;\n};\n\nconst BaseSwitch: React.FunctionComponent<PropsT> = ({\n label,\n onChange,\n options,\n theme,\n value,\n}) => {\n if (!options || !theme.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 = theme.option;\n let onPress: (() => void) | undefined;\n if (iValue === value) className += ` ${theme.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={theme.container}>\n {label ? <div className={theme.label}>{label}</div> : null}\n\n <div className={theme.options}>\n {optionNodes}\n </div>\n </div>\n );\n};\n\nexport default /* #__PURE__ */ themed(BaseSwitch, 'Switch', defaultTheme);\n"],"mappings":";;AAAA,OAAOA,MAAM,MAAsB,0BAA0B;AAAA,SAK3DC,eAAe;AAAA,MAAAC,YAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;AAAA;AAGuB,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAYxC,MAAMC,UAA2C,GAAGA,CAAC;EACnDC,KAAK;EACLC,QAAQ;EACRC,OAAO;EACPC,KAAK;EACLC;AACF,CAAC,KAAK;EACJ,IAAI,CAACF,OAAO,IAAI,CAACC,KAAK,CAACE,MAAM,EAAE,MAAMC,KAAK,CAAC,gBAAgB,CAAC;EAE5D,MAAMC,WAA8B,GAAG,EAAE;EACzC,KAAK,MAAMF,MAAM,IAAIH,OAAO,EAAE;IAC5B,MAAM,CAACM,MAAM,EAAEC,KAAK,CAAC,GAAGhB,eAAe,CAACY,MAAM,CAAC;IAE/C,IAAIK,SAAiB,GAAGP,KAAK,CAACE,MAAM;IACpC,IAAIM,OAAiC;IACrC,IAAIH,MAAM,KAAKJ,KAAK,EAAEM,SAAS,IAAI,IAAIP,KAAK,CAACS,QAAQ,EAAE,CAAC,KACnD,IAAIX,QAAQ,EAAE;MACjBU,OAAO,GAAGA,CAAA,KAAM;QACdV,QAAQ,CAACO,MAAM,CAAC;MAClB,CAAC;IACH;IAEAD,WAAW,CAACM,IAAI,CACdF,OAAO,gBAEHf,IAAA;MACEc,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,gBAENZ,IAAA;MAAKc,SAAS,EAAEA,SAAU;MAAAU,QAAA,EAAeX;IAAK,GAAdD,MAAoB,CAC1D,CAAC;EACH;EAEA,oBACEV,KAAA;IAAKY,SAAS,EAAEP,KAAK,CAACkB,SAAU;IAAAD,QAAA,GAC7BpB,KAAK,gBAAGJ,IAAA;MAAKc,SAAS,EAAEP,KAAK,CAACH,KAAM;MAAAoB,QAAA,EAAEpB;IAAK,CAAM,CAAC,GAAG,IAAI,eAE1DJ,IAAA;MAAKc,SAAS,EAAEP,KAAK,CAACD,OAAQ;MAAAkB,QAAA,EAC3Bb;IAAW,CACT,CAAC;EAAA,CACH,CAAC;AAEV,CAAC;AAED,eAAe,eAAgBf,MAAM,CAACO,UAAU,EAAE,QAAQ,EAAEL,YAAY,CAAC","ignoreList":[]}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Prepares and launches the app at client side.
|
|
4
4
|
* @param Application Root application component
|
|
5
5
|
* @param [options={}] Optional. Additional settings.
|
|
6
|
-
*/export
|
|
6
|
+
*/export async function launchClient(Application,options={}){const inj=await getInj();const container=document.getElementById("react-view");if(!container)throw Error("Failed to find container for React app");const scene=/*#__PURE__*/_jsx(GlobalStateProvider,{initialState:inj.ISTATE??options.initialState,children:/*#__PURE__*/_jsx(BrowserRouter,{children:/*#__PURE__*/_jsx(HelmetProvider,{children:/*#__PURE__*/_jsx(Application,{})})})});if(options.dontHydrate){const root=createRoot(container);root.render(scene)}else hydrateRoot(container,scene)}
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["createRoot","hydrateRoot","HelmetProvider","BrowserRouter","GlobalStateProvider","getInj","jsx","_jsx","
|
|
1
|
+
{"version":3,"file":"index.js","names":["createRoot","hydrateRoot","HelmetProvider","BrowserRouter","GlobalStateProvider","getInj","jsx","_jsx","launchClient","Application","options","inj","container","document","getElementById","Error","scene","initialState","ISTATE","children","dontHydrate","root","render"],"sources":["../../../src/client/index.tsx"],"sourcesContent":["// Initialization of client-side code.\n/* global document */\n\nimport type { ComponentType } from 'react';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\nimport { HelmetProvider } from '@dr.pogodin/react-helmet';\nimport { BrowserRouter } from 'react-router';\n\nimport { GlobalStateProvider } from '@dr.pogodin/react-global-state';\n\nimport getInj from './getInj';\n\ntype OptionsT = {\n dontHydrate?: boolean;\n initialState?: unknown;\n};\n\n/**\n * Prepares and launches the app at client side.\n * @param Application Root application component\n * @param [options={}] Optional. Additional settings.\n */\nexport async function launchClient(\n Application: ComponentType,\n options: OptionsT = {},\n): Promise<void> {\n const inj = await getInj();\n\n const container = document.getElementById('react-view');\n if (!container) throw Error('Failed to find container for React app');\n const scene = (\n <GlobalStateProvider initialState={inj.ISTATE ?? options.initialState}>\n <BrowserRouter>\n <HelmetProvider>\n <Application />\n </HelmetProvider>\n </BrowserRouter>\n </GlobalStateProvider>\n );\n\n if (options.dontHydrate) {\n const root = createRoot(container);\n root.render(scene);\n } else hydrateRoot(container, scene);\n}\n"],"mappings":"AAAA;AACA,qBAGA,OAASA,UAAU,CAAEC,WAAW,KAAQ,kBAAkB,CAC1D,OAASC,cAAc,KAAQ,0BAA0B,CACzD,OAASC,aAAa,KAAQ,cAAc,CAE5C,OAASC,mBAAmB,KAAQ,gCAAgC,OAE7D,CAAAC,MAAM,mBAAiB,OAAAC,GAAA,IAAAC,IAAA,yBAO9B;AACA;AACA;AACA;AACA,GACA,MAAO,eAAe,CAAAC,YAAYA,CAChCC,WAA0B,CAC1BC,OAAiB,CAAG,CAAC,CAAC,CACP,CACf,KAAM,CAAAC,GAAG,CAAG,KAAM,CAAAN,MAAM,CAAC,CAAC,CAE1B,KAAM,CAAAO,SAAS,CAAGC,QAAQ,CAACC,cAAc,CAAC,YAAY,CAAC,CACvD,GAAI,CAACF,SAAS,CAAE,KAAM,CAAAG,KAAK,CAAC,wCAAwC,CAAC,CACrE,KAAM,CAAAC,KAAK,cACTT,IAAA,CAACH,mBAAmB,EAACa,YAAY,CAAEN,GAAG,CAACO,MAAM,EAAIR,OAAO,CAACO,YAAa,CAAAE,QAAA,cACpEZ,IAAA,CAACJ,aAAa,EAAAgB,QAAA,cACZZ,IAAA,CAACL,cAAc,EAAAiB,QAAA,cACbZ,IAAA,CAACE,WAAW,GAAE,CAAC,CACD,CAAC,CACJ,CAAC,CACG,CACtB,CAED,GAAIC,OAAO,CAACU,WAAW,CAAE,CACvB,KAAM,CAAAC,IAAI,CAAGrB,UAAU,CAACY,SAAS,CAAC,CAClCS,IAAI,CAACC,MAAM,CAACN,KAAK,CACnB,CAAC,IAAM,CAAAf,WAAW,CAACW,SAAS,CAAEI,KAAK,CACrC","ignoreList":[]}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// It is a safeguard against multiple instances / versions of the library
|
|
2
2
|
// being loaded into environment by mistake (e.g. because of different
|
|
3
3
|
// packages pinning down different exact versions of the lib, thus preventing
|
|
4
4
|
// a proper dedupe and using a single common library version).
|
|
5
|
-
if(global.REACT_UTILS_LIBRARY_LOADED){throw Error("React utils library is already loaded")}else global.REACT_UTILS_LIBRARY_LOADED=true
|
|
6
|
-
// we'll re-implement requireWeak() to accept import.meta.url directly, and
|
|
7
|
-
// this workaround won't be needed.
|
|
8
|
-
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
|
|
9
|
-
const dirname=import.meta.dirname;const server=webpack.requireWeak("./server",dirname);const client=server?undefined:clientModule;export{getGlobalState,GlobalStateProvider,newAsyncDataEnvelope,useAsyncCollection,useAsyncData,useGlobalState,withGlobalStateType}from"@dr.pogodin/react-global-state";export*from"./shared/components/index.js";export{assertEmptyObject,Barrier,Cached,Emitter,getConfig,isomorphy,getSsrContext,Semaphore,splitComponent,themed,ThemeProvider,time,webpack,withRetries}from"./shared/utils/index.js";export{client,server};
|
|
5
|
+
if(global.REACT_UTILS_LIBRARY_LOADED){throw Error("React utils library is already loaded")}else global.REACT_UTILS_LIBRARY_LOADED=true;export{getGlobalState,GlobalStateProvider,newAsyncDataEnvelope,useAsyncCollection,useAsyncData,useGlobalState,withGlobalStateType}from"@dr.pogodin/react-global-state";export*from"./shared/components/index.js";export{assertEmptyObject,Barrier,Cached,Emitter,getConfig,isomorphy,getSsrContext,Semaphore,splitComponent,themed,ThemeProvider,time,webpack,withRetries}from"./shared/utils/index.js";
|
|
10
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["
|
|
1
|
+
{"version":3,"file":"index.js","names":["global","REACT_UTILS_LIBRARY_LOADED","Error","getGlobalState","GlobalStateProvider","newAsyncDataEnvelope","useAsyncCollection","useAsyncData","useGlobalState","withGlobalStateType","assertEmptyObject","Barrier","Cached","Emitter","getConfig","isomorphy","getSsrContext","Semaphore","splitComponent","themed","ThemeProvider","time","webpack","withRetries"],"sources":["../../src/index.ts"],"sourcesContent":["// It is a safeguard against multiple instances / versions of the library\n// being loaded into environment by mistake (e.g. because of different\n// packages pinning down different exact versions of the lib, thus preventing\n// a proper dedupe and using a single common library version).\nif (global.REACT_UTILS_LIBRARY_LOADED) {\n throw Error('React utils library is already loaded');\n} else global.REACT_UTILS_LIBRARY_LOADED = true;\n\nexport {\n type AsyncCollectionT,\n type AsyncCollectionLoaderT,\n type AsyncDataEnvelopeT,\n type AsyncDataLoaderT,\n type ForceT,\n type UseAsyncDataOptionsT,\n type UseAsyncDataResT,\n type UseGlobalStateResT,\n type ValueOrInitializerT,\n getGlobalState,\n GlobalStateProvider,\n newAsyncDataEnvelope,\n useAsyncCollection,\n useAsyncData,\n useGlobalState,\n withGlobalStateType,\n} from '@dr.pogodin/react-global-state';\n\nexport * from 'components';\n\nexport {\n type BeforeRenderResT,\n type BeforeRenderT,\n type ConfigT,\n type ServerSsrContext,\n type ServerT,\n} from './server';\n\nexport {\n assertEmptyObject,\n Barrier,\n Cached,\n Emitter,\n getConfig,\n isomorphy,\n getSsrContext,\n type Listener,\n type ObjectKey,\n Semaphore,\n splitComponent,\n type Theme,\n themed,\n ThemeProvider,\n time,\n webpack,\n withRetries,\n} from 'utils';\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA,GAAIA,MAAM,CAACC,0BAA0B,CAAE,CACrC,KAAM,CAAAC,KAAK,CAAC,uCAAuC,CACrD,CAAC,IAAM,CAAAF,MAAM,CAACC,0BAA0B,CAAG,IAAI,CAE/C,OAUEE,cAAc,CACdC,mBAAmB,CACnBC,oBAAoB,CACpBC,kBAAkB,CAClBC,YAAY,CACZC,cAAc,CACdC,mBAAmB,KACd,gCAAgC,kDAarCC,iBAAiB,CACjBC,OAAO,CACPC,MAAM,CACNC,OAAO,CACPC,SAAS,CACTC,SAAS,CACTC,aAAa,CAGbC,SAAS,CACTC,cAAc,CAEdC,MAAM,CACNC,aAAa,CACbC,IAAI,CACJC,OAAO,CACPC,WAAW","ignoreList":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import"source-map-support/register.js";import http from"node:http";import https from"node:https";import{cloneDeep,defaults}from"lodash-es";// Polyfill required by ReactJS.
|
|
3
3
|
// TODO: Double-check, if it is still required by React v19?
|
|
4
4
|
// eslint-disable-next-line import/no-unassigned-import
|
|
5
|
-
import"raf/polyfill.js";import serverFactory,{getDefaultCspSettings}from"./server.js";import{SCRIPT_LOCATIONS,newDefaultLogger}from"./renderer.js";
|
|
5
|
+
import"raf/polyfill.js";import serverFactory,{getDefaultCspSettings}from"./server.js";import{SCRIPT_LOCATIONS,newDefaultLogger}from"./renderer.js";export*from"./utils/index.js";export{getDefaultCspSettings,SCRIPT_LOCATIONS};/**
|
|
6
6
|
* Normalizes a port into a number, string, or false.
|
|
7
7
|
* TODO: Drop this function?
|
|
8
8
|
* @param value Port name or number.
|
|
@@ -124,8 +124,8 @@ import"raf/polyfill.js";import serverFactory,{getDefaultCspSettings}from"./serve
|
|
|
124
124
|
* @param {number} [options.ssrTimeout=1000] SSR timeout in milliseconds,
|
|
125
125
|
* defaults to 1 second.
|
|
126
126
|
* @return Resolves to an object with created Express and HTTP servers.
|
|
127
|
-
*/export
|
|
127
|
+
*/export async function launchServer(webpackConfig,options={}){/* Options normalization. */const ops=cloneDeep(options);// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
128
128
|
ops.port=normalizePort(ops.port||process.env.PORT||3000);defaults(ops,{httpsRedirect:true});// TODO: Need a separate type for normalized options, which guarantees
|
|
129
129
|
// the logger is set!
|
|
130
|
-
ops.logger??=newDefaultLogger({defaultLogLevel:ops.defaultLoggerLogLevel});/* Creates servers, resolves and sets the port. */const expressServer=await serverFactory(webpackConfig,ops);let httpServer;if(ops.https){httpServer=https.createServer({cert:ops.https.cert,key:ops.https.key},expressServer)}else httpServer=http.createServer(expressServer);/* Sets error handler for HTTP(S) server. */httpServer.on("error",error=>{if(error.syscall!=="listen")throw error;const bind=typeof ops.port==="string"?`Pipe ${ops.port}`:`Port ${ops.port}`;/* Human-readable message for some specific listen errors. */switch(error.code){case"EACCES":ops.logger.error(`${bind} requires elevated privileges`);return process.exit(1);case"EADDRINUSE":ops.logger.error(`${bind} is already in use`);return process.exit(1);case undefined:default:throw error}});/* Listening event handler for HTTP(S) server. */httpServer.on("listening",()=>{const addr=httpServer.address();const bind=typeof addr==="string"?`pipe ${addr}`:`port ${addr.port}`;ops.logger.info(`Server listening on ${bind} in ${process.env.NODE_ENV} mode`)});httpServer.listen(ops.port);return{expressServer,httpServer}}
|
|
130
|
+
ops.logger??=newDefaultLogger({defaultLogLevel:ops.defaultLoggerLogLevel});/* Creates servers, resolves and sets the port. */const expressServer=await serverFactory(webpackConfig,ops);let httpServer;if(ops.https){httpServer=https.createServer({cert:ops.https.cert,key:ops.https.key},expressServer)}else httpServer=http.createServer(expressServer);/* Sets error handler for HTTP(S) server. */httpServer.on("error",error=>{if(error.syscall!=="listen")throw error;const bind=typeof ops.port==="string"?`Pipe ${ops.port}`:`Port ${ops.port}`;/* Human-readable message for some specific listen errors. */switch(error.code){case"EACCES":ops.logger.error(`${bind} requires elevated privileges`);return process.exit(1);case"EADDRINUSE":ops.logger.error(`${bind} is already in use`);return process.exit(1);case undefined:default:throw error}});/* Listening event handler for HTTP(S) server. */httpServer.on("listening",()=>{const addr=httpServer.address();const bind=typeof addr==="string"?`pipe ${addr}`:`port ${addr.port}`;ops.logger.info(`Server listening on ${bind} in ${process.env.NODE_ENV} mode`)});httpServer.listen(ops.port);return{expressServer,httpServer}}
|
|
131
131
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["http","https","cloneDeep","defaults","serverFactory","getDefaultCspSettings","SCRIPT_LOCATIONS","newDefaultLogger","errors","normalizePort","value","port","parseInt","Number","isFinite","launchServer","webpackConfig","options","ops","process","env","PORT","httpsRedirect","logger","defaultLogLevel","defaultLoggerLogLevel","expressServer","httpServer","createServer","cert","key","on","error","syscall","bind","code","exit","undefined","addr","address","info","NODE_ENV","listen"],"sources":["../../../src/server/index.ts"],"sourcesContent":["// eslint-disable-next-line import/no-unassigned-import\nimport 'source-map-support/register.js';\n\nimport http from 'node:http';\nimport https from 'node:https';\n\nimport { cloneDeep, defaults } from 'lodash-es';\n\n// Polyfill required by ReactJS.\n// TODO: Double-check, if it is still required by React v19?\n// eslint-disable-next-line import/no-unassigned-import\nimport 'raf/polyfill.js';\n\nimport type { Configuration } from 'webpack';\n\nimport serverFactory, {\n type OptionsT as ServerOptionsT,\n type ServerT,\n getDefaultCspSettings,\n} from './server';\n\nimport { SCRIPT_LOCATIONS, newDefaultLogger } from './renderer';\n\nimport { errors } from './utils';\n\nexport type {\n BeforeRenderResT,\n BeforeRenderT,\n ConfigT,\n ServerSsrContext,\n} from './renderer';\n\nexport { errors, getDefaultCspSettings, type ServerT };\n\n/**\n * Normalizes a port into a number, string, or false.\n * TODO: Drop this function?\n * @param value Port name or number.\n * @return Port number (Number), name (String).\n */\nfunction normalizePort(value: number | string) {\n const port = typeof value === 'string' ? parseInt(value) : value;\n if (Number.isFinite(port)) return port; /* port number */\n return value; /* named pipe */\n}\n\ntype OptionsT = ServerOptionsT & {\n https?: {\n cert: string;\n key: string;\n };\n\n // TODO: Should we limit it to number | string, and throw if it is different value?\n port?: false | number | string;\n};\n\n/**\n * Creates and launches web-server for ReactJS application. Allows zero\n * or detailed configuration, supports server-side rendering,\n * and development tools, including Hot Module Reloading (HMR).\n *\n * NOTE: Many of options defined below are passed down to the server and\n * renderer factories, and their declared default values are set in those\n * factories, rather than here.\n *\n * @param {object} webpackConfig Webpack configuration used to build\n * the frontend bundle. In production mode the server will read out of it\n * `context`, `publicPath`, and a few other parameters, necessary to locate\n * and serve the app bundle. In development mode the server will use entire\n * provided config to build the app bundle in memory, and further watch and\n * update it via HMR.\n * @param {object} [options] Additional parameters.\n * @param {Component} [options.Application] The root ReactJS component of\n * the app to use for the server-side rendering. When not provided\n * the server-side rendering is disabled.\n * @param {function} [options.beforeExpressJsError] Asynchronous callback\n * (`(server) => Promise<boolean>`) to be executed just before the default error\n * handler is added to ExpressJS server. If the callback is provided and its\n * result resolves to a truthy value, `react-utils` won't attach the default\n * error handler.\n * @param {function} [options.beforeExpressJsSetup] Asynchronous callback\n * (`(server) => Promise) to be executed right after ExpressJS server creation,\n * before any configuration is performed.\n * @param {BeforeRenderHook} [options.beforeRender] The hook to run just before\n * the server-side rendering. For each incoming request, it will be executed\n * just before the HTML markup is generated at the server. It allows to load\n * and provide the data necessary for server-side rendering, and also to inject\n * additional configuration and scripts into the generated HTML code.\n * @param {boolean} [options.noCsp] Set `true` to disable\n * Content-Security-Policy (CSP) headers altogether.\n * @param {function} [options.cspSettingsHook] A hook allowing\n * to customize [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)\n * settings for [helmet](https://github.com/helmetjs/helmet)'s\n * `contentSecurityPolicy` middleware on per-request basis.\n *\n * If provided it should be a with signature: \\\n * `(defaultSettings: object, req: object)` ⇒ `object` \\\n * which gets the default settings (also used without the hook),\n * and the incoming request object. The hook response will be passed\n * as options to the helmet `contentSecurityPolicy` middleware.\n *\n * Currently, the default settings is the following object in production\n * environment:\n * ```js\n * {\n * directives: {\n * defaultSrc: [\"'self'\"],\n * baseUri: [\"'self'\"],\n * blockAllMixedContent: [],\n * fontSrc: [\"'self'\", 'https:', 'data:'],\n * frameAncestors: [\"'self'\"],\n * frameSrc: [\"'self'\", 'https://*.youtube.com'],\n * imgSrc: [\"'self'\", 'data:'],\n * objectSrc: [\"'none'\"],\n * scriptSrc: [\"'self'\", \"'unsafe-eval'\", `'nonce-UNIQUE_NONCE_VALUE'`],\n * scriptSrcAttr: [\"'none'\"],\n * styleSrc: [\"'self'\", 'https:', \"'unsafe-inline'\"],\n * upgradeInsecureRequests: [] // Removed in dev mode.\n * }\n * }\n * ```\n * It matches the default value used by Helmet with a few updates:\n * - YouTube host is whitelisted in the `frameSrc` directive to ensure\n * the {@link YouTubeVideo} component works.\n * - An unique per-request nonce is added to `scriptSrc` directive to\n * whitelist auxiliary scripts injected by react-utils. The actual nonce\n * value can be fetched by host code via `.nonce` field of `req` argument\n * of `.beforeRender` hook.\n * - `upgradeInsecureRequests` directive is removed in development mode,\n * to simplify local testing with http requests.\n * @param {string} [options.defaultLoggerLogLevel='info'] Log level for\n * the default logger, which is created if no `logger` option provided.\n * @param {boolean} [options.devMode] Pass in `true` to start the server in\n * development mode.\n * @param {string} [options.favicon] Path to the favicon to use by the server.\n * By default no favicon is used.\n * @param {object} [options.https] If provided, HTTPS server will be started,\n * instead of HTTP otherwise. The object should provide SSL certificate and key\n * via two string fields: `cert`, and `key`.\n * @param {string} [options.https.cert] SSL Certificate.\n * @param {string} [options.https.key] SSL key.\n * @param {boolean} [options.httpsRedirect=true] Pass in `true` to enable\n * automatic redirection of all incoming HTTP requests to HTTPS.\n *\n * To smoothly use it at `localhost` you need to run the server in HTTPS mode,\n * and also properly create and install a self-signed SSL sertificate on your\n * system. This article is helpful:\n * [How to get HTTPS working on your local development environment in 5 minutes](https://medium.freecodecamp.org/how-to-get-https-working-on-your-local-development-environment-in-5-minutes-7af615770eec)\n * @param {Logger} [options.logger] The logger to use at server side.\n * By default [`winston`](https://www.npmjs.com/package/winston) logger\n * with console transport is used. The logger you provide, or the default\n * `winston` logger otherwise, will be attached to the created ExpressJS server\n * object.\n * @param {function} [options.onExpressJsSetup] An async callback\n * (`(server) => Promise`) to be triggered when most of the server\n * configuration is completed, just before the server-side renderer,\n * and the default error handler are attached. You can use it to mount\n * custom API routes. The server-side logger can be accessed as `server.logger`.\n * @param {number|string} [options.port=3000] The port to start the server on.\n * @param {number} [options.staticCacheSize=1.e7] The maximum\n * static cache size in bytes. Defaults to ~10 MB.\n * @param {function} [options.staticCacheController] When given, it activates,\n * and controls the static caching of generated HTML markup. When this function\n * is provided, on each incoming request it is triggered with the request\n * passed in as the argument. To attempt to serve the response from the cache\n * it should return the object with the following fields:\n * - `key: string` – the cache key for the response;\n * - `maxage?: number` – the maximum age of cached result in ms.\n * If undefined - infinite age is assumed.\n * @param {number} [options.maxSsrRounds=10] Maximum number of SSR rounds.\n * @param {number} [options.ssrTimeout=1000] SSR timeout in milliseconds,\n * defaults to 1 second.\n * @return Resolves to an object with created Express and HTTP servers.\n */\nexport default async function launchServer(\n webpackConfig: Configuration,\n options: OptionsT = {},\n): Promise<{\n expressServer: ServerT;\n httpServer: http.Server;\n}> {\n /* Options normalization. */\n const ops = cloneDeep(options);\n\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n ops.port = normalizePort(ops.port || process.env.PORT || 3000);\n defaults(ops, { httpsRedirect: true });\n\n // TODO: Need a separate type for normalized options, which guarantees\n // the logger is set!\n ops.logger ??= newDefaultLogger({\n defaultLogLevel: ops.defaultLoggerLogLevel,\n });\n\n /* Creates servers, resolves and sets the port. */\n const expressServer = await serverFactory(webpackConfig, ops);\n\n let httpServer: http.Server;\n if (ops.https) {\n httpServer = https.createServer({\n cert: ops.https.cert,\n key: ops.https.key,\n }, expressServer as unknown as () => void);\n } else httpServer = http.createServer(expressServer as unknown as () => void);\n\n /* Sets error handler for HTTP(S) server. */\n httpServer.on('error', (error: Error) => {\n if ((error as { syscall?: string }).syscall !== 'listen') throw error;\n const bind = typeof ops.port === 'string' ? `Pipe ${ops.port}` : `Port ${ops.port}`;\n\n /* Human-readable message for some specific listen errors. */\n switch ((error as { code?: string }).code) {\n case 'EACCES':\n ops.logger!.error(`${bind} requires elevated privileges`);\n return process.exit(1);\n case 'EADDRINUSE':\n ops.logger!.error(`${bind} is already in use`);\n return process.exit(1);\n case undefined:\n default:\n throw error;\n }\n });\n\n /* Listening event handler for HTTP(S) server. */\n httpServer.on('listening', () => {\n const addr = httpServer.address()!;\n const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;\n ops.logger!.info(`Server listening on ${bind} in ${\n process.env.NODE_ENV} mode`);\n });\n\n httpServer.listen(ops.port);\n\n return {\n expressServer,\n httpServer,\n };\n}\n\nlaunchServer.SCRIPT_LOCATIONS = SCRIPT_LOCATIONS;\nlaunchServer.getDefaultCspSettings = getDefaultCspSettings;\nlaunchServer.errors = errors;\n"],"mappings":"AAAA;AACA,MAAO,gCAAgC,CAEvC,MAAO,CAAAA,IAAI,KAAM,WAAW,CAC5B,MAAO,CAAAC,KAAK,KAAM,YAAY,CAE9B,OAASC,SAAS,CAAEC,QAAQ,KAAQ,WAAW,CAE/C;AACA;AACA;AACA,MAAO,iBAAiB,OAIjB,CAAAC,aAAa,EAGlBC,qBAAqB,0BAGdC,gBAAgB,CAAEC,gBAAgB,4BAElCC,MAAM,wBASf,OAASA,MAAM,CAAEH,qBAAqB,EAEtC;AACA;AACA;AACA;AACA;AACA,GACA,QAAS,CAAAI,aAAaA,CAACC,KAAsB,CAAE,CAC7C,KAAM,CAAAC,IAAI,CAAG,MAAO,CAAAD,KAAK,GAAK,QAAQ,CAAGE,QAAQ,CAACF,KAAK,CAAC,CAAGA,KAAK,CAChE,GAAIG,MAAM,CAACC,QAAQ,CAACH,IAAI,CAAC,CAAE,MAAO,CAAAA,IAAI,CAAE,iBACxC,MAAO,CAAAD,KAAK,CAAE,gBAChB,CAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GACA,cAAe,eAAe,CAAAK,YAAYA,CACxCC,aAA4B,CAC5BC,OAAiB,CAAG,CAAC,CAAC,CAIrB,CACD,4BACA,KAAM,CAAAC,GAAG,CAAGhB,SAAS,CAACe,OAAO,CAAC,CAE9B;AACAC,GAAG,CAACP,IAAI,CAAGF,aAAa,CAACS,GAAG,CAACP,IAAI,EAAIQ,OAAO,CAACC,GAAG,CAACC,IAAI,EAAI,IAAI,CAAC,CAC9DlB,QAAQ,CAACe,GAAG,CAAE,CAAEI,aAAa,CAAE,IAAK,CAAC,CAAC,CAEtC;AACA;AACAJ,GAAG,CAACK,MAAM,GAAKhB,gBAAgB,CAAC,CAC9BiB,eAAe,CAAEN,GAAG,CAACO,qBACvB,CAAC,CAAC,CAEF,kDACA,KAAM,CAAAC,aAAa,CAAG,KAAM,CAAAtB,aAAa,CAACY,aAAa,CAAEE,GAAG,CAAC,CAE7D,GAAI,CAAAS,UAAuB,CAC3B,GAAIT,GAAG,CAACjB,KAAK,CAAE,CACb0B,UAAU,CAAG1B,KAAK,CAAC2B,YAAY,CAAC,CAC9BC,IAAI,CAAEX,GAAG,CAACjB,KAAK,CAAC4B,IAAI,CACpBC,GAAG,CAAEZ,GAAG,CAACjB,KAAK,CAAC6B,GACjB,CAAC,CAAEJ,aAAsC,CAC3C,CAAC,IAAM,CAAAC,UAAU,CAAG3B,IAAI,CAAC4B,YAAY,CAACF,aAAsC,CAAC,CAE7E,4CACAC,UAAU,CAACI,EAAE,CAAC,OAAO,CAAGC,KAAY,EAAK,CACvC,GAAKA,KAAK,CAA0BC,OAAO,GAAK,QAAQ,CAAE,KAAM,CAAAD,KAAK,CACrE,KAAM,CAAAE,IAAI,CAAG,MAAO,CAAAhB,GAAG,CAACP,IAAI,GAAK,QAAQ,CAAG,QAAQO,GAAG,CAACP,IAAI,EAAE,CAAG,QAAQO,GAAG,CAACP,IAAI,EAAE,CAEnF,6DACA,OAASqB,KAAK,CAAuBG,IAAI,EACvC,IAAK,QAAQ,CACXjB,GAAG,CAACK,MAAM,CAAES,KAAK,CAAC,GAAGE,IAAI,+BAA+B,CAAC,CACzD,MAAO,CAAAf,OAAO,CAACiB,IAAI,CAAC,CAAC,CAAC,CACxB,IAAK,YAAY,CACflB,GAAG,CAACK,MAAM,CAAES,KAAK,CAAC,GAAGE,IAAI,oBAAoB,CAAC,CAC9C,MAAO,CAAAf,OAAO,CAACiB,IAAI,CAAC,CAAC,CAAC,CACxB,IAAK,CAAAC,SAAS,CACd,QACE,KAAM,CAAAL,KACV,CACF,CAAC,CAAC,CAEF,iDACAL,UAAU,CAACI,EAAE,CAAC,WAAW,CAAE,IAAM,CAC/B,KAAM,CAAAO,IAAI,CAAGX,UAAU,CAACY,OAAO,CAAC,CAAE,CAClC,KAAM,CAAAL,IAAI,CAAG,MAAO,CAAAI,IAAI,GAAK,QAAQ,CAAG,QAAQA,IAAI,EAAE,CAAG,QAAQA,IAAI,CAAC3B,IAAI,EAAE,CAC5EO,GAAG,CAACK,MAAM,CAAEiB,IAAI,CAAC,uBAAuBN,IAAI,OAC1Cf,OAAO,CAACC,GAAG,CAACqB,QAAQ,OAAO,CAC/B,CAAC,CAAC,CAEFd,UAAU,CAACe,MAAM,CAACxB,GAAG,CAACP,IAAI,CAAC,CAE3B,MAAO,CACLe,aAAa,CACbC,UACF,CACF,CAEAZ,YAAY,CAACT,gBAAgB,CAAGA,gBAAgB,CAChDS,YAAY,CAACV,qBAAqB,CAAGA,qBAAqB,CAC1DU,YAAY,CAACP,MAAM,CAAGA,MAAM","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["http","https","cloneDeep","defaults","serverFactory","getDefaultCspSettings","SCRIPT_LOCATIONS","newDefaultLogger","normalizePort","value","port","parseInt","Number","isFinite","launchServer","webpackConfig","options","ops","process","env","PORT","httpsRedirect","logger","defaultLogLevel","defaultLoggerLogLevel","expressServer","httpServer","createServer","cert","key","on","error","syscall","bind","code","exit","undefined","addr","address","info","NODE_ENV","listen"],"sources":["../../../src/server/index.ts"],"sourcesContent":["// eslint-disable-next-line import/no-unassigned-import\nimport 'source-map-support/register.js';\n\nimport http from 'node:http';\nimport https from 'node:https';\n\nimport { cloneDeep, defaults } from 'lodash-es';\n\n// Polyfill required by ReactJS.\n// TODO: Double-check, if it is still required by React v19?\n// eslint-disable-next-line import/no-unassigned-import\nimport 'raf/polyfill.js';\n\nimport type { Configuration } from 'webpack';\n\nimport serverFactory, {\n type OptionsT as ServerOptionsT,\n type ServerT,\n getDefaultCspSettings,\n} from './server';\n\nimport { SCRIPT_LOCATIONS, newDefaultLogger } from './renderer';\n\nexport * from './utils';\n\nexport type {\n BeforeRenderResT,\n BeforeRenderT,\n ConfigT,\n ServerSsrContext,\n} from './renderer';\n\nexport {\n getDefaultCspSettings,\n SCRIPT_LOCATIONS,\n type ServerT,\n};\n\n/**\n * Normalizes a port into a number, string, or false.\n * TODO: Drop this function?\n * @param value Port name or number.\n * @return Port number (Number), name (String).\n */\nfunction normalizePort(value: number | string) {\n const port = typeof value === 'string' ? parseInt(value) : value;\n if (Number.isFinite(port)) return port; /* port number */\n return value; /* named pipe */\n}\n\ntype OptionsT = ServerOptionsT & {\n https?: {\n cert: string;\n key: string;\n };\n\n // TODO: Should we limit it to number | string, and throw if it is different value?\n port?: false | number | string;\n};\n\n/**\n * Creates and launches web-server for ReactJS application. Allows zero\n * or detailed configuration, supports server-side rendering,\n * and development tools, including Hot Module Reloading (HMR).\n *\n * NOTE: Many of options defined below are passed down to the server and\n * renderer factories, and their declared default values are set in those\n * factories, rather than here.\n *\n * @param {object} webpackConfig Webpack configuration used to build\n * the frontend bundle. In production mode the server will read out of it\n * `context`, `publicPath`, and a few other parameters, necessary to locate\n * and serve the app bundle. In development mode the server will use entire\n * provided config to build the app bundle in memory, and further watch and\n * update it via HMR.\n * @param {object} [options] Additional parameters.\n * @param {Component} [options.Application] The root ReactJS component of\n * the app to use for the server-side rendering. When not provided\n * the server-side rendering is disabled.\n * @param {function} [options.beforeExpressJsError] Asynchronous callback\n * (`(server) => Promise<boolean>`) to be executed just before the default error\n * handler is added to ExpressJS server. If the callback is provided and its\n * result resolves to a truthy value, `react-utils` won't attach the default\n * error handler.\n * @param {function} [options.beforeExpressJsSetup] Asynchronous callback\n * (`(server) => Promise) to be executed right after ExpressJS server creation,\n * before any configuration is performed.\n * @param {BeforeRenderHook} [options.beforeRender] The hook to run just before\n * the server-side rendering. For each incoming request, it will be executed\n * just before the HTML markup is generated at the server. It allows to load\n * and provide the data necessary for server-side rendering, and also to inject\n * additional configuration and scripts into the generated HTML code.\n * @param {boolean} [options.noCsp] Set `true` to disable\n * Content-Security-Policy (CSP) headers altogether.\n * @param {function} [options.cspSettingsHook] A hook allowing\n * to customize [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)\n * settings for [helmet](https://github.com/helmetjs/helmet)'s\n * `contentSecurityPolicy` middleware on per-request basis.\n *\n * If provided it should be a with signature: \\\n * `(defaultSettings: object, req: object)` ⇒ `object` \\\n * which gets the default settings (also used without the hook),\n * and the incoming request object. The hook response will be passed\n * as options to the helmet `contentSecurityPolicy` middleware.\n *\n * Currently, the default settings is the following object in production\n * environment:\n * ```js\n * {\n * directives: {\n * defaultSrc: [\"'self'\"],\n * baseUri: [\"'self'\"],\n * blockAllMixedContent: [],\n * fontSrc: [\"'self'\", 'https:', 'data:'],\n * frameAncestors: [\"'self'\"],\n * frameSrc: [\"'self'\", 'https://*.youtube.com'],\n * imgSrc: [\"'self'\", 'data:'],\n * objectSrc: [\"'none'\"],\n * scriptSrc: [\"'self'\", \"'unsafe-eval'\", `'nonce-UNIQUE_NONCE_VALUE'`],\n * scriptSrcAttr: [\"'none'\"],\n * styleSrc: [\"'self'\", 'https:', \"'unsafe-inline'\"],\n * upgradeInsecureRequests: [] // Removed in dev mode.\n * }\n * }\n * ```\n * It matches the default value used by Helmet with a few updates:\n * - YouTube host is whitelisted in the `frameSrc` directive to ensure\n * the {@link YouTubeVideo} component works.\n * - An unique per-request nonce is added to `scriptSrc` directive to\n * whitelist auxiliary scripts injected by react-utils. The actual nonce\n * value can be fetched by host code via `.nonce` field of `req` argument\n * of `.beforeRender` hook.\n * - `upgradeInsecureRequests` directive is removed in development mode,\n * to simplify local testing with http requests.\n * @param {string} [options.defaultLoggerLogLevel='info'] Log level for\n * the default logger, which is created if no `logger` option provided.\n * @param {boolean} [options.devMode] Pass in `true` to start the server in\n * development mode.\n * @param {string} [options.favicon] Path to the favicon to use by the server.\n * By default no favicon is used.\n * @param {object} [options.https] If provided, HTTPS server will be started,\n * instead of HTTP otherwise. The object should provide SSL certificate and key\n * via two string fields: `cert`, and `key`.\n * @param {string} [options.https.cert] SSL Certificate.\n * @param {string} [options.https.key] SSL key.\n * @param {boolean} [options.httpsRedirect=true] Pass in `true` to enable\n * automatic redirection of all incoming HTTP requests to HTTPS.\n *\n * To smoothly use it at `localhost` you need to run the server in HTTPS mode,\n * and also properly create and install a self-signed SSL sertificate on your\n * system. This article is helpful:\n * [How to get HTTPS working on your local development environment in 5 minutes](https://medium.freecodecamp.org/how-to-get-https-working-on-your-local-development-environment-in-5-minutes-7af615770eec)\n * @param {Logger} [options.logger] The logger to use at server side.\n * By default [`winston`](https://www.npmjs.com/package/winston) logger\n * with console transport is used. The logger you provide, or the default\n * `winston` logger otherwise, will be attached to the created ExpressJS server\n * object.\n * @param {function} [options.onExpressJsSetup] An async callback\n * (`(server) => Promise`) to be triggered when most of the server\n * configuration is completed, just before the server-side renderer,\n * and the default error handler are attached. You can use it to mount\n * custom API routes. The server-side logger can be accessed as `server.logger`.\n * @param {number|string} [options.port=3000] The port to start the server on.\n * @param {number} [options.staticCacheSize=1.e7] The maximum\n * static cache size in bytes. Defaults to ~10 MB.\n * @param {function} [options.staticCacheController] When given, it activates,\n * and controls the static caching of generated HTML markup. When this function\n * is provided, on each incoming request it is triggered with the request\n * passed in as the argument. To attempt to serve the response from the cache\n * it should return the object with the following fields:\n * - `key: string` – the cache key for the response;\n * - `maxage?: number` – the maximum age of cached result in ms.\n * If undefined - infinite age is assumed.\n * @param {number} [options.maxSsrRounds=10] Maximum number of SSR rounds.\n * @param {number} [options.ssrTimeout=1000] SSR timeout in milliseconds,\n * defaults to 1 second.\n * @return Resolves to an object with created Express and HTTP servers.\n */\nexport async function launchServer(\n webpackConfig: Configuration,\n options: OptionsT = {},\n): Promise<{\n expressServer: ServerT;\n httpServer: http.Server;\n}> {\n /* Options normalization. */\n const ops = cloneDeep(options);\n\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n ops.port = normalizePort(ops.port || process.env.PORT || 3000);\n defaults(ops, { httpsRedirect: true });\n\n // TODO: Need a separate type for normalized options, which guarantees\n // the logger is set!\n ops.logger ??= newDefaultLogger({\n defaultLogLevel: ops.defaultLoggerLogLevel,\n });\n\n /* Creates servers, resolves and sets the port. */\n const expressServer = await serverFactory(webpackConfig, ops);\n\n let httpServer: http.Server;\n if (ops.https) {\n httpServer = https.createServer({\n cert: ops.https.cert,\n key: ops.https.key,\n }, expressServer as unknown as () => void);\n } else httpServer = http.createServer(expressServer as unknown as () => void);\n\n /* Sets error handler for HTTP(S) server. */\n httpServer.on('error', (error: Error) => {\n if ((error as { syscall?: string }).syscall !== 'listen') throw error;\n const bind = typeof ops.port === 'string' ? `Pipe ${ops.port}` : `Port ${ops.port}`;\n\n /* Human-readable message for some specific listen errors. */\n switch ((error as { code?: string }).code) {\n case 'EACCES':\n ops.logger!.error(`${bind} requires elevated privileges`);\n return process.exit(1);\n case 'EADDRINUSE':\n ops.logger!.error(`${bind} is already in use`);\n return process.exit(1);\n case undefined:\n default:\n throw error;\n }\n });\n\n /* Listening event handler for HTTP(S) server. */\n httpServer.on('listening', () => {\n const addr = httpServer.address()!;\n const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;\n ops.logger!.info(`Server listening on ${bind} in ${\n process.env.NODE_ENV} mode`);\n });\n\n httpServer.listen(ops.port);\n\n return {\n expressServer,\n httpServer,\n };\n}\n"],"mappings":"AAAA;AACA,MAAO,gCAAgC,CAEvC,MAAO,CAAAA,IAAI,KAAM,WAAW,CAC5B,MAAO,CAAAC,KAAK,KAAM,YAAY,CAE9B,OAASC,SAAS,CAAEC,QAAQ,KAAQ,WAAW,CAE/C;AACA;AACA;AACA,MAAO,iBAAiB,OAIjB,CAAAC,aAAa,EAGlBC,qBAAqB,0BAGdC,gBAAgB,CAAEC,gBAAgB,mDAW3C,OACEF,qBAAqB,CACrBC,gBAAgB,EAIlB;AACA;AACA;AACA;AACA;AACA,GACA,QAAS,CAAAE,aAAaA,CAACC,KAAsB,CAAE,CAC7C,KAAM,CAAAC,IAAI,CAAG,MAAO,CAAAD,KAAK,GAAK,QAAQ,CAAGE,QAAQ,CAACF,KAAK,CAAC,CAAGA,KAAK,CAChE,GAAIG,MAAM,CAACC,QAAQ,CAACH,IAAI,CAAC,CAAE,MAAO,CAAAA,IAAI,CAAE,iBACxC,MAAO,CAAAD,KAAK,CAAE,gBAChB,CAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GACA,MAAO,eAAe,CAAAK,YAAYA,CAChCC,aAA4B,CAC5BC,OAAiB,CAAG,CAAC,CAAC,CAIrB,CACD,4BACA,KAAM,CAAAC,GAAG,CAAGf,SAAS,CAACc,OAAO,CAAC,CAE9B;AACAC,GAAG,CAACP,IAAI,CAAGF,aAAa,CAACS,GAAG,CAACP,IAAI,EAAIQ,OAAO,CAACC,GAAG,CAACC,IAAI,EAAI,IAAI,CAAC,CAC9DjB,QAAQ,CAACc,GAAG,CAAE,CAAEI,aAAa,CAAE,IAAK,CAAC,CAAC,CAEtC;AACA;AACAJ,GAAG,CAACK,MAAM,GAAKf,gBAAgB,CAAC,CAC9BgB,eAAe,CAAEN,GAAG,CAACO,qBACvB,CAAC,CAAC,CAEF,kDACA,KAAM,CAAAC,aAAa,CAAG,KAAM,CAAArB,aAAa,CAACW,aAAa,CAAEE,GAAG,CAAC,CAE7D,GAAI,CAAAS,UAAuB,CAC3B,GAAIT,GAAG,CAAChB,KAAK,CAAE,CACbyB,UAAU,CAAGzB,KAAK,CAAC0B,YAAY,CAAC,CAC9BC,IAAI,CAAEX,GAAG,CAAChB,KAAK,CAAC2B,IAAI,CACpBC,GAAG,CAAEZ,GAAG,CAAChB,KAAK,CAAC4B,GACjB,CAAC,CAAEJ,aAAsC,CAC3C,CAAC,IAAM,CAAAC,UAAU,CAAG1B,IAAI,CAAC2B,YAAY,CAACF,aAAsC,CAAC,CAE7E,4CACAC,UAAU,CAACI,EAAE,CAAC,OAAO,CAAGC,KAAY,EAAK,CACvC,GAAKA,KAAK,CAA0BC,OAAO,GAAK,QAAQ,CAAE,KAAM,CAAAD,KAAK,CACrE,KAAM,CAAAE,IAAI,CAAG,MAAO,CAAAhB,GAAG,CAACP,IAAI,GAAK,QAAQ,CAAG,QAAQO,GAAG,CAACP,IAAI,EAAE,CAAG,QAAQO,GAAG,CAACP,IAAI,EAAE,CAEnF,6DACA,OAASqB,KAAK,CAAuBG,IAAI,EACvC,IAAK,QAAQ,CACXjB,GAAG,CAACK,MAAM,CAAES,KAAK,CAAC,GAAGE,IAAI,+BAA+B,CAAC,CACzD,MAAO,CAAAf,OAAO,CAACiB,IAAI,CAAC,CAAC,CAAC,CACxB,IAAK,YAAY,CACflB,GAAG,CAACK,MAAM,CAAES,KAAK,CAAC,GAAGE,IAAI,oBAAoB,CAAC,CAC9C,MAAO,CAAAf,OAAO,CAACiB,IAAI,CAAC,CAAC,CAAC,CACxB,IAAK,CAAAC,SAAS,CACd,QACE,KAAM,CAAAL,KACV,CACF,CAAC,CAAC,CAEF,iDACAL,UAAU,CAACI,EAAE,CAAC,WAAW,CAAE,IAAM,CAC/B,KAAM,CAAAO,IAAI,CAAGX,UAAU,CAACY,OAAO,CAAC,CAAE,CAClC,KAAM,CAAAL,IAAI,CAAG,MAAO,CAAAI,IAAI,GAAK,QAAQ,CAAG,QAAQA,IAAI,EAAE,CAAG,QAAQA,IAAI,CAAC3B,IAAI,EAAE,CAC5EO,GAAG,CAACK,MAAM,CAAEiB,IAAI,CAAC,uBAAuBN,IAAI,OAC1Cf,OAAO,CAACC,GAAG,CAACqB,QAAQ,OAAO,CAC/B,CAAC,CAAC,CAEFd,UAAU,CAACe,MAAM,CAACxB,GAAG,CAACP,IAAI,CAAC,CAE3B,MAAO,CACLe,aAAa,CACbC,UACF,CACF","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/server/utils/index.ts"],"sourcesContent":["// Aggregates utility modules together.\n\nexport * from './errors';\n"],"mappings":"AAAA;AAAA","ignoreList":[]}
|
|
@@ -10,5 +10,5 @@ import themed from"@dr.pogodin/react-themes";import Link from"../Link.js";const
|
|
|
10
10
|
* @prop {string} [active] to the root element of active button.
|
|
11
11
|
* @prop {string} [button] to the root element of any button.
|
|
12
12
|
* @prop {string} [disabled] to the root element of disabled button.
|
|
13
|
-
*/export default themed(BaseButton,"Button",defaultTheme);
|
|
13
|
+
*/export default/* #__PURE__ */themed(BaseButton,"Button",defaultTheme);
|
|
14
14
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["themed","Link","defaultTheme","jsx","_jsx","BaseButton","active","children","disabled","enforceA","onClick","onKeyDown","onKeyDownProp","onKeyUp","onMouseDown","onMouseUp","onPointerDown","onPointerUp","openNewTab","replace","testId","theme","to","className","button","process","env","NODE_ENV","undefined","e","key","role","tabIndex"],"sources":["../../../../../src/shared/components/Button/index.tsx"],"sourcesContent":["// The <Button> component implements a standard button / button-like link.\n\nimport type {\n FunctionComponent,\n KeyboardEventHandler,\n MouseEventHandler,\n PointerEventHandler,\n ReactNode,\n} from 'react';\n\nimport themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport Link from 'components/Link';\n\nimport defaultTheme from './style.scss';\n\ntype PropsT = {\n active?: boolean;\n children?: ReactNode;\n disabled?: boolean;\n enforceA?: boolean;\n onClick?: MouseEventHandler & KeyboardEventHandler;\n onKeyDown?: KeyboardEventHandler;\n onKeyUp?: KeyboardEventHandler;\n onMouseDown?: MouseEventHandler;\n onMouseUp?: MouseEventHandler;\n onPointerDown?: PointerEventHandler;\n onPointerUp?: PointerEventHandler;\n openNewTab?: boolean;\n replace?: boolean;\n testId?: string;\n theme: Theme<'active' | 'button' | 'disabled'>;\n // TODO: It needs a more precise typing of the object option.\n to?: object | string;\n};\n\nexport const BaseButton: FunctionComponent<PropsT> = ({\n active,\n children,\n disabled,\n enforceA,\n onClick,\n onKeyDown: onKeyDownProp,\n onKeyUp,\n onMouseDown,\n onMouseUp,\n onPointerDown,\n onPointerUp,\n openNewTab,\n replace,\n testId,\n theme,\n to,\n}) => {\n let className = theme.button;\n if (active && theme.active) className += ` ${theme.active}`;\n if (disabled) {\n if (theme.disabled) className += ` ${theme.disabled}`;\n return (\n <div\n className={className}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n >\n {children}\n </div>\n );\n }\n\n let onKeyDown = onKeyDownProp;\n if (!onKeyDown && onClick) {\n onKeyDown = (e) => {\n if (e.key === 'Enter') onClick(e);\n };\n }\n\n if (to) {\n return (\n <Link\n className={className}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n enforceA={enforceA}\n onClick={onClick}\n\n // TODO: For now, the `onKeyDown` handler is not passed to the <Link>,\n // as <Link> component does not call it anyway, presumably due to\n // the inner implementation details. We should look into supporting it:\n // https://github.com/birdofpreyru/react-utils/issues/444\n // onKeyDown={onKeyDown}\n\n onKeyUp={onKeyUp}\n onMouseDown={onMouseDown}\n onMouseUp={onMouseUp}\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n openNewTab={openNewTab}\n replace={replace}\n to={to}\n >\n {children}\n </Link>\n );\n }\n\n return (\n <div\n className={className}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n onClick={onClick}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n onMouseDown={onMouseDown}\n onMouseUp={onMouseUp}\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n role=\"button\"\n tabIndex={0}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Button component theme: a map of CSS\n * class names to append to button elements:\n * @prop {string} [active] to the root element of active button.\n * @prop {string} [button] to the root element of any button.\n * @prop {string} [disabled] to the root element of disabled button.\n */\nexport default themed(BaseButton, 'Button', defaultTheme);\n"],"mappings":"AAAA;AAUA,MAAO,CAAAA,MAAM,KAAsB,0BAA0B,OAEtD,CAAAC,IAAI,wBAAAC,YAAA,6GAE6B,OAAAC,GAAA,IAAAC,IAAA,yBAsBxC,MAAO,MAAM,CAAAC,UAAqC,CAAGA,CAAC,CACpDC,MAAM,CACNC,QAAQ,CACRC,QAAQ,CACRC,QAAQ,CACRC,OAAO,CACPC,SAAS,CAAEC,aAAa,CACxBC,OAAO,CACPC,WAAW,CACXC,SAAS,CACTC,aAAa,CACbC,WAAW,CACXC,UAAU,CACVC,OAAO,CACPC,MAAM,CACNC,KAAK,CACLC,EACF,CAAC,GAAK,CACJ,GAAI,CAAAC,SAAS,CAAGF,KAAK,CAACG,MAAM,CAC5B,GAAIlB,MAAM,EAAIe,KAAK,CAACf,MAAM,CAAEiB,SAAS,EAAI,IAAIF,KAAK,CAACf,MAAM,EAAE,CAC3D,GAAIE,QAAQ,CAAE,CACZ,GAAIa,KAAK,CAACb,QAAQ,CAAEe,SAAS,EAAI,IAAIF,KAAK,CAACb,QAAQ,EAAE,CACrD,mBACEJ,IAAA,QACEmB,SAAS,CAAEA,SAAU,CACrB,cAAaE,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGC,SAAS,CAAGR,MAAO,CAAAb,QAAA,CAEvEA,QAAQ,CACN,CAET,CAEA,GAAI,CAAAI,SAAS,CAAGC,aAAa,CAC7B,GAAI,CAACD,SAAS,EAAID,OAAO,CAAE,CACzBC,SAAS,CAAIkB,CAAC,EAAK,CACjB,GAAIA,CAAC,CAACC,GAAG,GAAK,OAAO,CAAEpB,OAAO,CAACmB,CAAC,CAClC,CACF,CAEA,GAAIP,EAAE,CAAE,CACN,mBACElB,IAAA,CAACH,IAAI,EACHsB,SAAS,CAAEA,SAAU,CACrB,cAAaE,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGC,SAAS,CAAGR,MAAO,CACxEX,QAAQ,CAAEA,QAAS,CACnBC,OAAO,CAAEA,OAET;AACA;AACA;AACA;AACA;AAAA,CAEAG,OAAO,CAAEA,OAAQ,CACjBC,WAAW,CAAEA,WAAY,CACzBC,SAAS,CAAEA,SAAU,CACrBC,aAAa,CAAEA,aAAc,CAC7BC,WAAW,CAAEA,WAAY,CACzBC,UAAU,CAAEA,UAAW,CACvBC,OAAO,CAAEA,OAAQ,CACjBG,EAAE,CAAEA,EAAG,CAAAf,QAAA,CAENA,QAAQ,CACL,CAEV,CAEA,mBACEH,IAAA,QACEmB,SAAS,CAAEA,SAAU,CACrB,cAAaE,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGC,SAAS,CAAGR,MAAO,CACxEV,OAAO,CAAEA,OAAQ,CACjBC,SAAS,CAAEA,SAAU,CACrBE,OAAO,CAAEA,OAAQ,CACjBC,WAAW,CAAEA,WAAY,CACzBC,SAAS,CAAEA,SAAU,CACrBC,aAAa,CAAEA,aAAc,CAC7BC,WAAW,CAAEA,WAAY,CACzBc,IAAI,CAAC,QAAQ,CACbC,QAAQ,CAAE,CAAE,CAAAzB,QAAA,CAEXA,QAAQ,CACN,CAET,CAAC,CAED;AACA;AACA;AACA;AACA;AACA;AACA,GACA,cAAe,
|
|
1
|
+
{"version":3,"file":"index.js","names":["themed","Link","defaultTheme","jsx","_jsx","BaseButton","active","children","disabled","enforceA","onClick","onKeyDown","onKeyDownProp","onKeyUp","onMouseDown","onMouseUp","onPointerDown","onPointerUp","openNewTab","replace","testId","theme","to","className","button","process","env","NODE_ENV","undefined","e","key","role","tabIndex"],"sources":["../../../../../src/shared/components/Button/index.tsx"],"sourcesContent":["// The <Button> component implements a standard button / button-like link.\n\nimport type {\n FunctionComponent,\n KeyboardEventHandler,\n MouseEventHandler,\n PointerEventHandler,\n ReactNode,\n} from 'react';\n\nimport themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport Link from 'components/Link';\n\nimport defaultTheme from './style.scss';\n\ntype PropsT = {\n active?: boolean;\n children?: ReactNode;\n disabled?: boolean;\n enforceA?: boolean;\n onClick?: MouseEventHandler & KeyboardEventHandler;\n onKeyDown?: KeyboardEventHandler;\n onKeyUp?: KeyboardEventHandler;\n onMouseDown?: MouseEventHandler;\n onMouseUp?: MouseEventHandler;\n onPointerDown?: PointerEventHandler;\n onPointerUp?: PointerEventHandler;\n openNewTab?: boolean;\n replace?: boolean;\n testId?: string;\n theme: Theme<'active' | 'button' | 'disabled'>;\n // TODO: It needs a more precise typing of the object option.\n to?: object | string;\n};\n\nexport const BaseButton: FunctionComponent<PropsT> = ({\n active,\n children,\n disabled,\n enforceA,\n onClick,\n onKeyDown: onKeyDownProp,\n onKeyUp,\n onMouseDown,\n onMouseUp,\n onPointerDown,\n onPointerUp,\n openNewTab,\n replace,\n testId,\n theme,\n to,\n}) => {\n let className = theme.button;\n if (active && theme.active) className += ` ${theme.active}`;\n if (disabled) {\n if (theme.disabled) className += ` ${theme.disabled}`;\n return (\n <div\n className={className}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n >\n {children}\n </div>\n );\n }\n\n let onKeyDown = onKeyDownProp;\n if (!onKeyDown && onClick) {\n onKeyDown = (e) => {\n if (e.key === 'Enter') onClick(e);\n };\n }\n\n if (to) {\n return (\n <Link\n className={className}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n enforceA={enforceA}\n onClick={onClick}\n\n // TODO: For now, the `onKeyDown` handler is not passed to the <Link>,\n // as <Link> component does not call it anyway, presumably due to\n // the inner implementation details. We should look into supporting it:\n // https://github.com/birdofpreyru/react-utils/issues/444\n // onKeyDown={onKeyDown}\n\n onKeyUp={onKeyUp}\n onMouseDown={onMouseDown}\n onMouseUp={onMouseUp}\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n openNewTab={openNewTab}\n replace={replace}\n to={to}\n >\n {children}\n </Link>\n );\n }\n\n return (\n <div\n className={className}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n onClick={onClick}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n onMouseDown={onMouseDown}\n onMouseUp={onMouseUp}\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n role=\"button\"\n tabIndex={0}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Button component theme: a map of CSS\n * class names to append to button elements:\n * @prop {string} [active] to the root element of active button.\n * @prop {string} [button] to the root element of any button.\n * @prop {string} [disabled] to the root element of disabled button.\n */\nexport default /* #__PURE__ */ themed(BaseButton, 'Button', defaultTheme);\n"],"mappings":"AAAA;AAUA,MAAO,CAAAA,MAAM,KAAsB,0BAA0B,OAEtD,CAAAC,IAAI,wBAAAC,YAAA,6GAE6B,OAAAC,GAAA,IAAAC,IAAA,yBAsBxC,MAAO,MAAM,CAAAC,UAAqC,CAAGA,CAAC,CACpDC,MAAM,CACNC,QAAQ,CACRC,QAAQ,CACRC,QAAQ,CACRC,OAAO,CACPC,SAAS,CAAEC,aAAa,CACxBC,OAAO,CACPC,WAAW,CACXC,SAAS,CACTC,aAAa,CACbC,WAAW,CACXC,UAAU,CACVC,OAAO,CACPC,MAAM,CACNC,KAAK,CACLC,EACF,CAAC,GAAK,CACJ,GAAI,CAAAC,SAAS,CAAGF,KAAK,CAACG,MAAM,CAC5B,GAAIlB,MAAM,EAAIe,KAAK,CAACf,MAAM,CAAEiB,SAAS,EAAI,IAAIF,KAAK,CAACf,MAAM,EAAE,CAC3D,GAAIE,QAAQ,CAAE,CACZ,GAAIa,KAAK,CAACb,QAAQ,CAAEe,SAAS,EAAI,IAAIF,KAAK,CAACb,QAAQ,EAAE,CACrD,mBACEJ,IAAA,QACEmB,SAAS,CAAEA,SAAU,CACrB,cAAaE,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGC,SAAS,CAAGR,MAAO,CAAAb,QAAA,CAEvEA,QAAQ,CACN,CAET,CAEA,GAAI,CAAAI,SAAS,CAAGC,aAAa,CAC7B,GAAI,CAACD,SAAS,EAAID,OAAO,CAAE,CACzBC,SAAS,CAAIkB,CAAC,EAAK,CACjB,GAAIA,CAAC,CAACC,GAAG,GAAK,OAAO,CAAEpB,OAAO,CAACmB,CAAC,CAClC,CACF,CAEA,GAAIP,EAAE,CAAE,CACN,mBACElB,IAAA,CAACH,IAAI,EACHsB,SAAS,CAAEA,SAAU,CACrB,cAAaE,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGC,SAAS,CAAGR,MAAO,CACxEX,QAAQ,CAAEA,QAAS,CACnBC,OAAO,CAAEA,OAET;AACA;AACA;AACA;AACA;AAAA,CAEAG,OAAO,CAAEA,OAAQ,CACjBC,WAAW,CAAEA,WAAY,CACzBC,SAAS,CAAEA,SAAU,CACrBC,aAAa,CAAEA,aAAc,CAC7BC,WAAW,CAAEA,WAAY,CACzBC,UAAU,CAAEA,UAAW,CACvBC,OAAO,CAAEA,OAAQ,CACjBG,EAAE,CAAEA,EAAG,CAAAf,QAAA,CAENA,QAAQ,CACL,CAEV,CAEA,mBACEH,IAAA,QACEmB,SAAS,CAAEA,SAAU,CACrB,cAAaE,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGC,SAAS,CAAGR,MAAO,CACxEV,OAAO,CAAEA,OAAQ,CACjBC,SAAS,CAAEA,SAAU,CACrBE,OAAO,CAAEA,OAAQ,CACjBC,WAAW,CAAEA,WAAY,CACzBC,SAAS,CAAEA,SAAU,CACrBC,aAAa,CAAEA,aAAc,CAC7BC,WAAW,CAAEA,WAAY,CACzBc,IAAI,CAAC,QAAQ,CACbC,QAAQ,CAAE,CAAE,CAAAzB,QAAA,CAEXA,QAAQ,CACN,CAET,CAAC,CAED;AACA;AACA;AACA;AACA;AACA;AACA,GACA,cAAe,eAAgBP,MAAM,CAACK,UAAU,CAAE,QAAQ,CAAEH,YAAY,CAAC","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import themed from"@dr.pogodin/react-themes";const defaultTheme={"context":"_08mmmo","ad":"Hc06MV","hoc":"toOtOd","checkbox":"v4DmWM","indeterminate":"ckSC8W","container":"g7wee9","label":"XQ57WS","disabled":"baVvQA"};import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const Checkbox=({checked,disabled,label,onChange,testId,theme})=>{let containerClassName=theme.container;if(disabled)containerClassName+=` ${theme.disabled}`;let checkboxClassName=theme.checkbox;if(checked==="indeterminate")checkboxClassName+=` ${theme.indeterminate}`;return/*#__PURE__*/_jsxs("div",{className:containerClassName,children:[label===undefined?null:/*#__PURE__*/_jsx("div",{className:theme.label,children:label}),/*#__PURE__*/_jsx("input",{checked:checked===undefined?undefined:checked===true,className:checkboxClassName,"data-testid":process.env.NODE_ENV==="production"?undefined:testId,disabled:disabled,onChange:onChange,onClick:e=>{e.stopPropagation()},type:"checkbox"})]})};export default themed(Checkbox,"Checkbox",defaultTheme);
|
|
1
|
+
import themed from"@dr.pogodin/react-themes";const defaultTheme={"context":"_08mmmo","ad":"Hc06MV","hoc":"toOtOd","checkbox":"v4DmWM","indeterminate":"ckSC8W","container":"g7wee9","label":"XQ57WS","disabled":"baVvQA"};import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const Checkbox=({checked,disabled,label,onChange,testId,theme})=>{let containerClassName=theme.container;if(disabled)containerClassName+=` ${theme.disabled}`;let checkboxClassName=theme.checkbox;if(checked==="indeterminate")checkboxClassName+=` ${theme.indeterminate}`;return/*#__PURE__*/_jsxs("div",{className:containerClassName,children:[label===undefined?null:/*#__PURE__*/_jsx("div",{className:theme.label,children:label}),/*#__PURE__*/_jsx("input",{checked:checked===undefined?undefined:checked===true,className:checkboxClassName,"data-testid":process.env.NODE_ENV==="production"?undefined:testId,disabled:disabled,onChange:onChange,onClick:e=>{e.stopPropagation()},type:"checkbox"})]})};export default/* #__PURE__ */themed(Checkbox,"Checkbox",defaultTheme);
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["themed","defaultTheme","jsx","_jsx","jsxs","_jsxs","Checkbox","checked","disabled","label","onChange","testId","theme","containerClassName","container","checkboxClassName","checkbox","indeterminate","className","children","undefined","process","env","NODE_ENV","onClick","e","stopPropagation","type"],"sources":["../../../../../src/shared/components/Checkbox/index.tsx"],"sourcesContent":["import themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport defaultTheme from './theme.scss';\n\ntype PropT<ValueT> = {\n checked?: ValueT;\n disabled?: boolean;\n label?: React.ReactNode;\n onChange?: React.ChangeEventHandler<HTMLInputElement>;\n testId?: string;\n theme: Theme<\n | 'checkbox'\n | 'container'\n | 'disabled'\n | 'indeterminate'\n | 'label'\n >;\n};\n\nconst Checkbox = <ValueT extends boolean | 'indeterminate' = boolean>({\n checked,\n disabled,\n label,\n onChange,\n testId,\n theme,\n}: PropT<ValueT>) => {\n let containerClassName = theme.container;\n if (disabled) containerClassName += ` ${theme.disabled}`;\n\n let checkboxClassName = theme.checkbox;\n if (checked === 'indeterminate') checkboxClassName += ` ${theme.indeterminate}`;\n\n return (\n <div className={containerClassName}>\n { label === undefined\n ? null : <div className={theme.label}>{label}</div> }\n <input\n checked={checked === undefined ? undefined : checked === true}\n className={checkboxClassName}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n disabled={disabled}\n onChange={onChange}\n onClick={(e) => {\n e.stopPropagation();\n }}\n type=\"checkbox\"\n />\n </div>\n );\n};\n\nexport default themed(Checkbox, 'Checkbox', defaultTheme);\n"],"mappings":"AAAA,MAAO,CAAAA,MAAM,KAAsB,0BAA0B,OAAAC,YAAA,2JAErB,OAAAC,GAAA,IAAAC,IAAA,CAAAC,IAAA,IAAAC,KAAA,yBAiBxC,KAAM,CAAAC,QAAQ,CAAGA,CAAqD,CACpEC,OAAO,CACPC,QAAQ,CACRC,KAAK,CACLC,QAAQ,CACRC,MAAM,CACNC,KACa,CAAC,GAAK,CACnB,GAAI,CAAAC,kBAAkB,CAAGD,KAAK,CAACE,SAAS,CACxC,GAAIN,QAAQ,CAAEK,kBAAkB,EAAI,IAAID,KAAK,CAACJ,QAAQ,EAAE,CAExD,GAAI,CAAAO,iBAAiB,CAAGH,KAAK,CAACI,QAAQ,CACtC,GAAIT,OAAO,GAAK,eAAe,CAAEQ,iBAAiB,EAAI,IAAIH,KAAK,CAACK,aAAa,EAAE,CAE/E,mBACEZ,KAAA,QAAKa,SAAS,CAAEL,kBAAmB,CAAAM,QAAA,EAC/BV,KAAK,GAAKW,SAAS,CACjB,IAAI,cAAGjB,IAAA,QAAKe,SAAS,CAAEN,KAAK,CAACH,KAAM,CAAAU,QAAA,CAAEV,KAAK,CAAM,CAAC,cACrDN,IAAA,UACEI,OAAO,CAAEA,OAAO,GAAKa,SAAS,CAAGA,SAAS,CAAGb,OAAO,GAAK,IAAK,CAC9DW,SAAS,CAAEH,iBAAkB,CAC7B,cAAaM,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGH,SAAS,CAAGT,MAAO,CACxEH,QAAQ,CAAEA,QAAS,CACnBE,QAAQ,CAAEA,QAAS,CACnBc,OAAO,CAAGC,CAAC,EAAK,CACdA,CAAC,CAACC,eAAe,CAAC,CACpB,CAAE,CACFC,IAAI,CAAC,UAAU,CAChB,CAAC,EACC,CAET,CAAC,CAED,cAAe,
|
|
1
|
+
{"version":3,"file":"index.js","names":["themed","defaultTheme","jsx","_jsx","jsxs","_jsxs","Checkbox","checked","disabled","label","onChange","testId","theme","containerClassName","container","checkboxClassName","checkbox","indeterminate","className","children","undefined","process","env","NODE_ENV","onClick","e","stopPropagation","type"],"sources":["../../../../../src/shared/components/Checkbox/index.tsx"],"sourcesContent":["import themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport defaultTheme from './theme.scss';\n\ntype PropT<ValueT> = {\n checked?: ValueT;\n disabled?: boolean;\n label?: React.ReactNode;\n onChange?: React.ChangeEventHandler<HTMLInputElement>;\n testId?: string;\n theme: Theme<\n | 'checkbox'\n | 'container'\n | 'disabled'\n | 'indeterminate'\n | 'label'\n >;\n};\n\nconst Checkbox = <ValueT extends boolean | 'indeterminate' = boolean>({\n checked,\n disabled,\n label,\n onChange,\n testId,\n theme,\n}: PropT<ValueT>) => {\n let containerClassName = theme.container;\n if (disabled) containerClassName += ` ${theme.disabled}`;\n\n let checkboxClassName = theme.checkbox;\n if (checked === 'indeterminate') checkboxClassName += ` ${theme.indeterminate}`;\n\n return (\n <div className={containerClassName}>\n { label === undefined\n ? null : <div className={theme.label}>{label}</div> }\n <input\n checked={checked === undefined ? undefined : checked === true}\n className={checkboxClassName}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n disabled={disabled}\n onChange={onChange}\n onClick={(e) => {\n e.stopPropagation();\n }}\n type=\"checkbox\"\n />\n </div>\n );\n};\n\nexport default /* #__PURE__ */ themed(Checkbox, 'Checkbox', defaultTheme);\n"],"mappings":"AAAA,MAAO,CAAAA,MAAM,KAAsB,0BAA0B,OAAAC,YAAA,2JAErB,OAAAC,GAAA,IAAAC,IAAA,CAAAC,IAAA,IAAAC,KAAA,yBAiBxC,KAAM,CAAAC,QAAQ,CAAGA,CAAqD,CACpEC,OAAO,CACPC,QAAQ,CACRC,KAAK,CACLC,QAAQ,CACRC,MAAM,CACNC,KACa,CAAC,GAAK,CACnB,GAAI,CAAAC,kBAAkB,CAAGD,KAAK,CAACE,SAAS,CACxC,GAAIN,QAAQ,CAAEK,kBAAkB,EAAI,IAAID,KAAK,CAACJ,QAAQ,EAAE,CAExD,GAAI,CAAAO,iBAAiB,CAAGH,KAAK,CAACI,QAAQ,CACtC,GAAIT,OAAO,GAAK,eAAe,CAAEQ,iBAAiB,EAAI,IAAIH,KAAK,CAACK,aAAa,EAAE,CAE/E,mBACEZ,KAAA,QAAKa,SAAS,CAAEL,kBAAmB,CAAAM,QAAA,EAC/BV,KAAK,GAAKW,SAAS,CACjB,IAAI,cAAGjB,IAAA,QAAKe,SAAS,CAAEN,KAAK,CAACH,KAAM,CAAAU,QAAA,CAAEV,KAAK,CAAM,CAAC,cACrDN,IAAA,UACEI,OAAO,CAAEA,OAAO,GAAKa,SAAS,CAAGA,SAAS,CAAGb,OAAO,GAAK,IAAK,CAC9DW,SAAS,CAAEH,iBAAkB,CAC7B,cAAaM,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGH,SAAS,CAAGT,MAAO,CACxEH,QAAQ,CAAEA,QAAS,CACnBE,QAAQ,CAAEA,QAAS,CACnBc,OAAO,CAAGC,CAAC,EAAK,CACdA,CAAC,CAACC,eAAe,CAAC,CACpB,CAAE,CACFC,IAAI,CAAC,UAAU,CAChB,CAAC,EACC,CAET,CAAC,CAED,cAAe,eAAgB3B,MAAM,CAACM,QAAQ,CAAE,UAAU,CAAEL,YAAY,CAAC","ignoreList":[]}
|
|
@@ -14,5 +14,5 @@ if(focused/* && theme.focused */)containerClassName+=` ${theme.focused}`;if(!res
|
|
|
14
14
|
// the case we need it for.
|
|
15
15
|
if(typeof ref==="object")ref?.current?.focus();else localRef.current?.focus()},children:[label===undefined?null:/*#__PURE__*/_jsx("div",{className:theme.label,children:label}),/*#__PURE__*/_jsx("input",{className:theme.input,"data-testid":process.env.NODE_ENV==="production"?undefined:testId,ref:ref??localRef// TODO: Avoid the spreading later.
|
|
16
16
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
17
|
-
,...rest,onBlur:theme.focused?e=>{setFocused(false);rest.onBlur?.(e)}:rest.onBlur,onFocus:theme.focused?e=>{setFocused(true);rest.onFocus?.(e)}:rest.onFocus}),error&&error!==true?/*#__PURE__*/_jsx("div",{className:theme.errorMessage,children:error}):null,children?/*#__PURE__*/_jsx("div",{className:theme.children,children:children}):null]})};export default themed(Input,"Input",defaultTheme);
|
|
17
|
+
,...rest,onBlur:theme.focused?e=>{setFocused(false);rest.onBlur?.(e)}:rest.onBlur,onFocus:theme.focused?e=>{setFocused(true);rest.onFocus?.(e)}:rest.onFocus}),error&&error!==true?/*#__PURE__*/_jsx("div",{className:theme.errorMessage,children:error}):null,children?/*#__PURE__*/_jsx("div",{className:theme.children,children:children}):null]})};export default/* #__PURE__ */themed(Input,"Input",defaultTheme);
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useRef","useState","themed","defaultTheme","jsx","_jsx","jsxs","_jsxs","Input","children","error","label","ref","testId","theme","rest","focused","setFocused","localRef","containerClassName","container","value","empty","className","onFocus","current","focus","undefined","input","process","env","NODE_ENV","onBlur","e","errorMessage"],"sources":["../../../../../src/shared/components/Input/index.tsx"],"sourcesContent":["import {\n type FunctionComponent,\n type ReactNode,\n type Ref,\n useRef,\n useState,\n} from 'react';\n\nimport themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport defaultTheme from './theme.scss';\n\ntype ThemeKeyT = 'children' | 'container' | 'empty' | 'error' | 'errorMessage'\n | 'focused' | 'input' | 'label';\n\ntype PropsT = React.InputHTMLAttributes<HTMLInputElement> & {\n children?: ReactNode;\n error?: ReactNode;\n label?: React.ReactNode;\n ref?: Ref<HTMLInputElement>;\n testId?: string;\n theme: Theme<ThemeKeyT>;\n};\n\n/**\n * Themeable input field, based on the standard HTML `<input>` element.\n * @param [props.label] Input label.\n * @param [props.theme] _Ad hoc_ theme.\n * @param [props...] [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)\n * @param [props...] Any other properties are passed to the underlying\n * `<input>` element.\n */\nconst Input: FunctionComponent<PropsT> = ({\n children,\n error,\n label,\n ref,\n testId,\n theme,\n ...rest\n}) => {\n // NOTE: As of now, it is only updated when \"theme.focused\" is defined,\n // as otherwise its value is not used.\n const [focused, setFocused] = useState(false);\n\n const localRef = useRef<HTMLInputElement>(null);\n\n let containerClassName = theme.container;\n\n // NOTE: As of now, \"focused\" can be true only when \"theme.focused\"\n // is provided.\n if (focused /* && theme.focused */) containerClassName += ` ${theme.focused}`;\n\n if (!rest.value && theme.empty) containerClassName += ` ${theme.empty}`;\n\n if (error) containerClassName += ` ${theme.error}`;\n\n return (\n <div\n className={containerClassName}\n onFocus={() => {\n // TODO: It does not really work if a callback-style `ref` is passed in,\n // we need a more complex logic to cover that case, but for now this serves\n // the case we need it for.\n if (typeof ref === 'object') ref?.current?.focus();\n else localRef.current?.focus();\n }}\n >\n {label === undefined ? null : <div className={theme.label}>{label}</div>}\n <input\n className={theme.input}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n ref={ref ?? localRef}\n\n // TODO: Avoid the spreading later.\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...rest}\n\n onBlur={theme.focused ? (e) => {\n setFocused(false);\n rest.onBlur?.(e);\n } : rest.onBlur}\n onFocus={theme.focused ? (e) => {\n setFocused(true);\n rest.onFocus?.(e);\n } : rest.onFocus}\n />\n {error && error !== true\n ? <div className={theme.errorMessage}>{error}</div>\n : null}\n {children ? <div className={theme.children}>{children}</div> : null}\n </div>\n );\n};\n\nexport default themed(Input, 'Input', defaultTheme);\n"],"mappings":"AAAA,OAIEA,MAAM,CACNC,QAAQ,KACH,OAAO,CAEd,MAAO,CAAAC,MAAM,KAAsB,0BAA0B,OAAAC,YAAA,wKAErB,OAAAC,GAAA,IAAAC,IAAA,CAAAC,IAAA,IAAAC,KAAA,yBAcxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GACA,KAAM,CAAAC,KAAgC,CAAGA,CAAC,CACxCC,QAAQ,CACRC,KAAK,CACLC,KAAK,CACLC,GAAG,CACHC,MAAM,CACNC,KAAK,CACL,GAAGC,IACL,CAAC,GAAK,CACJ;AACA;AACA,KAAM,CAACC,OAAO,CAAEC,UAAU,CAAC,CAAGhB,QAAQ,CAAC,KAAK,CAAC,CAE7C,KAAM,CAAAiB,QAAQ,CAAGlB,MAAM,CAAmB,IAAI,CAAC,CAE/C,GAAI,CAAAmB,kBAAkB,CAAGL,KAAK,CAACM,SAAS,CAExC;AACA;AACA,GAAIJ,OAAQ,uBAAwBG,kBAAkB,EAAI,IAAIL,KAAK,CAACE,OAAO,EAAE,CAE7E,GAAI,CAACD,IAAI,CAACM,KAAK,EAAIP,KAAK,CAACQ,KAAK,CAAEH,kBAAkB,EAAI,IAAIL,KAAK,CAACQ,KAAK,EAAE,CAEvE,GAAIZ,KAAK,CAAES,kBAAkB,EAAI,IAAIL,KAAK,CAACJ,KAAK,EAAE,CAElD,mBACEH,KAAA,QACEgB,SAAS,CAAEJ,kBAAmB,CAC9BK,OAAO,CAAEA,CAAA,GAAM,CACb;AACA;AACA;AACA,GAAI,MAAO,CAAAZ,GAAG,GAAK,QAAQ,CAAEA,GAAG,EAAEa,OAAO,EAAEC,KAAK,CAAC,CAAC,CAAC,IAC9C,CAAAR,QAAQ,CAACO,OAAO,EAAEC,KAAK,CAAC,CAC/B,CAAE,CAAAjB,QAAA,EAEDE,KAAK,GAAKgB,SAAS,CAAG,IAAI,cAAGtB,IAAA,QAAKkB,SAAS,CAAET,KAAK,CAACH,KAAM,CAAAF,QAAA,CAAEE,KAAK,CAAM,CAAC,cACxEN,IAAA,UACEkB,SAAS,CAAET,KAAK,CAACc,KAAM,CACvB,cAAaC,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGJ,SAAS,CAAGd,MAAO,CACxED,GAAG,CAAEA,GAAG,EAAIM,QAEZ;AACA;AAAA,IACIH,IAAI,CAERiB,MAAM,CAAElB,KAAK,CAACE,OAAO,CAAIiB,CAAC,EAAK,CAC7BhB,UAAU,CAAC,KAAK,CAAC,CACjBF,IAAI,CAACiB,MAAM,GAAGC,CAAC,CACjB,CAAC,CAAGlB,IAAI,CAACiB,MAAO,CAChBR,OAAO,CAAEV,KAAK,CAACE,OAAO,CAAIiB,CAAC,EAAK,CAC9BhB,UAAU,CAAC,IAAI,CAAC,CAChBF,IAAI,CAACS,OAAO,GAAGS,CAAC,CAClB,CAAC,CAAGlB,IAAI,CAACS,OAAQ,CAClB,CAAC,CACDd,KAAK,EAAIA,KAAK,GAAK,IAAI,cACpBL,IAAA,QAAKkB,SAAS,CAAET,KAAK,CAACoB,YAAa,CAAAzB,QAAA,CAAEC,KAAK,CAAM,CAAC,CACjD,IAAI,CACPD,QAAQ,cAAGJ,IAAA,QAAKkB,SAAS,CAAET,KAAK,CAACL,QAAS,CAAAA,QAAA,CAAEA,QAAQ,CAAM,CAAC,CAAG,IAAI,EAChE,CAET,CAAC,CAED,cAAe,
|
|
1
|
+
{"version":3,"file":"index.js","names":["useRef","useState","themed","defaultTheme","jsx","_jsx","jsxs","_jsxs","Input","children","error","label","ref","testId","theme","rest","focused","setFocused","localRef","containerClassName","container","value","empty","className","onFocus","current","focus","undefined","input","process","env","NODE_ENV","onBlur","e","errorMessage"],"sources":["../../../../../src/shared/components/Input/index.tsx"],"sourcesContent":["import {\n type FunctionComponent,\n type ReactNode,\n type Ref,\n useRef,\n useState,\n} from 'react';\n\nimport themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport defaultTheme from './theme.scss';\n\ntype ThemeKeyT = 'children' | 'container' | 'empty' | 'error' | 'errorMessage'\n | 'focused' | 'input' | 'label';\n\ntype PropsT = React.InputHTMLAttributes<HTMLInputElement> & {\n children?: ReactNode;\n error?: ReactNode;\n label?: React.ReactNode;\n ref?: Ref<HTMLInputElement>;\n testId?: string;\n theme: Theme<ThemeKeyT>;\n};\n\n/**\n * Themeable input field, based on the standard HTML `<input>` element.\n * @param [props.label] Input label.\n * @param [props.theme] _Ad hoc_ theme.\n * @param [props...] [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)\n * @param [props...] Any other properties are passed to the underlying\n * `<input>` element.\n */\nconst Input: FunctionComponent<PropsT> = ({\n children,\n error,\n label,\n ref,\n testId,\n theme,\n ...rest\n}) => {\n // NOTE: As of now, it is only updated when \"theme.focused\" is defined,\n // as otherwise its value is not used.\n const [focused, setFocused] = useState(false);\n\n const localRef = useRef<HTMLInputElement>(null);\n\n let containerClassName = theme.container;\n\n // NOTE: As of now, \"focused\" can be true only when \"theme.focused\"\n // is provided.\n if (focused /* && theme.focused */) containerClassName += ` ${theme.focused}`;\n\n if (!rest.value && theme.empty) containerClassName += ` ${theme.empty}`;\n\n if (error) containerClassName += ` ${theme.error}`;\n\n return (\n <div\n className={containerClassName}\n onFocus={() => {\n // TODO: It does not really work if a callback-style `ref` is passed in,\n // we need a more complex logic to cover that case, but for now this serves\n // the case we need it for.\n if (typeof ref === 'object') ref?.current?.focus();\n else localRef.current?.focus();\n }}\n >\n {label === undefined ? null : <div className={theme.label}>{label}</div>}\n <input\n className={theme.input}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n ref={ref ?? localRef}\n\n // TODO: Avoid the spreading later.\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...rest}\n\n onBlur={theme.focused ? (e) => {\n setFocused(false);\n rest.onBlur?.(e);\n } : rest.onBlur}\n onFocus={theme.focused ? (e) => {\n setFocused(true);\n rest.onFocus?.(e);\n } : rest.onFocus}\n />\n {error && error !== true\n ? <div className={theme.errorMessage}>{error}</div>\n : null}\n {children ? <div className={theme.children}>{children}</div> : null}\n </div>\n );\n};\n\nexport default /* #__PURE__ */ themed(Input, 'Input', defaultTheme);\n"],"mappings":"AAAA,OAIEA,MAAM,CACNC,QAAQ,KACH,OAAO,CAEd,MAAO,CAAAC,MAAM,KAAsB,0BAA0B,OAAAC,YAAA,wKAErB,OAAAC,GAAA,IAAAC,IAAA,CAAAC,IAAA,IAAAC,KAAA,yBAcxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GACA,KAAM,CAAAC,KAAgC,CAAGA,CAAC,CACxCC,QAAQ,CACRC,KAAK,CACLC,KAAK,CACLC,GAAG,CACHC,MAAM,CACNC,KAAK,CACL,GAAGC,IACL,CAAC,GAAK,CACJ;AACA;AACA,KAAM,CAACC,OAAO,CAAEC,UAAU,CAAC,CAAGhB,QAAQ,CAAC,KAAK,CAAC,CAE7C,KAAM,CAAAiB,QAAQ,CAAGlB,MAAM,CAAmB,IAAI,CAAC,CAE/C,GAAI,CAAAmB,kBAAkB,CAAGL,KAAK,CAACM,SAAS,CAExC;AACA;AACA,GAAIJ,OAAQ,uBAAwBG,kBAAkB,EAAI,IAAIL,KAAK,CAACE,OAAO,EAAE,CAE7E,GAAI,CAACD,IAAI,CAACM,KAAK,EAAIP,KAAK,CAACQ,KAAK,CAAEH,kBAAkB,EAAI,IAAIL,KAAK,CAACQ,KAAK,EAAE,CAEvE,GAAIZ,KAAK,CAAES,kBAAkB,EAAI,IAAIL,KAAK,CAACJ,KAAK,EAAE,CAElD,mBACEH,KAAA,QACEgB,SAAS,CAAEJ,kBAAmB,CAC9BK,OAAO,CAAEA,CAAA,GAAM,CACb;AACA;AACA;AACA,GAAI,MAAO,CAAAZ,GAAG,GAAK,QAAQ,CAAEA,GAAG,EAAEa,OAAO,EAAEC,KAAK,CAAC,CAAC,CAAC,IAC9C,CAAAR,QAAQ,CAACO,OAAO,EAAEC,KAAK,CAAC,CAC/B,CAAE,CAAAjB,QAAA,EAEDE,KAAK,GAAKgB,SAAS,CAAG,IAAI,cAAGtB,IAAA,QAAKkB,SAAS,CAAET,KAAK,CAACH,KAAM,CAAAF,QAAA,CAAEE,KAAK,CAAM,CAAC,cACxEN,IAAA,UACEkB,SAAS,CAAET,KAAK,CAACc,KAAM,CACvB,cAAaC,OAAO,CAACC,GAAG,CAACC,QAAQ,GAAK,YAAY,CAAGJ,SAAS,CAAGd,MAAO,CACxED,GAAG,CAAEA,GAAG,EAAIM,QAEZ;AACA;AAAA,IACIH,IAAI,CAERiB,MAAM,CAAElB,KAAK,CAACE,OAAO,CAAIiB,CAAC,EAAK,CAC7BhB,UAAU,CAAC,KAAK,CAAC,CACjBF,IAAI,CAACiB,MAAM,GAAGC,CAAC,CACjB,CAAC,CAAGlB,IAAI,CAACiB,MAAO,CAChBR,OAAO,CAAEV,KAAK,CAACE,OAAO,CAAIiB,CAAC,EAAK,CAC9BhB,UAAU,CAAC,IAAI,CAAC,CAChBF,IAAI,CAACS,OAAO,GAAGS,CAAC,CAClB,CAAC,CAAGlB,IAAI,CAACS,OAAQ,CAClB,CAAC,CACDd,KAAK,EAAIA,KAAK,GAAK,IAAI,cACpBL,IAAA,QAAKkB,SAAS,CAAET,KAAK,CAACoB,YAAa,CAAAzB,QAAA,CAAEC,KAAK,CAAM,CAAC,CACjD,IAAI,CACPD,QAAQ,cAAGJ,IAAA,QAAKkB,SAAS,CAAET,KAAK,CAACL,QAAS,CAAAA,QAAA,CAAEA,QAAQ,CAAM,CAAC,CAAG,IAAI,EAChE,CAET,CAAC,CAED,cAAe,eAAgBP,MAAM,CAACM,KAAK,CAAE,OAAO,CAAEL,YAAY,CAAC","ignoreList":[]}
|
|
@@ -15,5 +15,5 @@ useEffect(()=>{if(!dontDisableScrolling){document.body.classList.add(S.scrolling
|
|
|
15
15
|
,tabIndex:0}),[]);return/*#__PURE__*/createPortal(/*#__PURE__*/_jsxs("div",{children:[focusLast,/*#__PURE__*/_jsx("div",{"aria-label":"Cancel",className:theme.overlay,"data-testid":process.env.NODE_ENV==="production"?undefined:testIdForOverlay,onClick:e=>{if(onCancel){onCancel();e.stopPropagation()}},onKeyDown:e=>{if(e.key==="Escape"&&onCancel){onCancel();e.stopPropagation()}},ref:node=>{if(node&&node!==overlayRef.current){overlayRef.current=node;node.focus()}},role:"button",style:overlayStyle,tabIndex:0}),/*#__PURE__*/_jsx("div",{// eslint-disable-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions
|
|
16
16
|
"aria-modal":"true",className:theme.container,"data-testid":process.env.NODE_ENV==="production"?undefined:testId,onClick:e=>{e.stopPropagation()},onWheel:event=>{event.stopPropagation()},ref:containerRef,role:"dialog",style:style??containerStyle,children:children}),/*#__PURE__*/_jsx("div",{onFocus:()=>{overlayRef.current?.focus()}// TODO: Have a look at this later.
|
|
17
17
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
18
|
-
,tabIndex:0}),focusLast]}),document.body)};export default themed(BaseModal,"Modal",baseTheme);/* Non-themed version of the Modal. */export{BaseModal};
|
|
18
|
+
,tabIndex:0}),focusLast]}),document.body)};export default/* #__PURE__ */themed(BaseModal,"Modal",baseTheme);/* Non-themed version of the Modal. */export{BaseModal};
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useEffect","useMemo","useRef","createPortal","themed","baseTheme","S","jsx","_jsx","jsxs","_jsxs","BaseModal","cancelOnScrolling","children","containerStyle","dontDisableScrolling","onCancel","overlayStyle","style","testId","testIdForOverlay","theme","containerRef","overlayRef","window","addEventListener","removeEventListener","document","body","classList","add","scrollingDisabledByModal","remove","focusLast","onFocus","elems","current","querySelectorAll","i","length","focus","activeElement","tabIndex","className","overlay","process","env","NODE_ENV","undefined","onClick","e","stopPropagation","onKeyDown","key","ref","node","role","container","onWheel","event"],"sources":["../../../../../src/shared/components/Modal/index.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type FunctionComponent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\n\nimport { createPortal } from 'react-dom';\nimport themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport baseTheme from './base-theme.scss';\nimport S from './styles.scss';\n\ntype PropsT = {\n cancelOnScrolling?: boolean;\n children?: ReactNode;\n dontDisableScrolling?: boolean;\n onCancel?: () => void;\n overlayStyle?: CSSProperties;\n style?: CSSProperties;\n testId?: string;\n testIdForOverlay?: string;\n theme: Theme<'container' | 'overlay'>;\n\n /** @deprecated */\n containerStyle?: CSSProperties;\n};\n\n/**\n * The `<Modal>` component implements a simple themeable modal window, wrapped\n * into the default theme. `<BaseModal>` exposes the base non-themed component.\n * **Children:** Component children are rendered as the modal content.\n * @param {object} props Component properties. Beside props documented below,\n * [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties) are supported as well.\n * @param {function} [props.onCancel] The callback to trigger when user\n * clicks outside the modal, or presses Escape. It is expected to hide the\n * modal.\n * @param {ModalTheme} [props.theme] _Ad hoc_ theme.\n */\nconst BaseModal: FunctionComponent<PropsT> = ({\n cancelOnScrolling,\n children,\n containerStyle,\n dontDisableScrolling,\n onCancel,\n overlayStyle,\n style,\n testId,\n testIdForOverlay,\n theme,\n}) => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const overlayRef = useRef<HTMLDivElement | null>(null);\n\n // Sets up modal cancellation of scrolling, if opted-in.\n useEffect(() => {\n if (cancelOnScrolling && onCancel) {\n window.addEventListener('scroll', onCancel);\n window.addEventListener('wheel', onCancel);\n }\n return () => {\n if (cancelOnScrolling && onCancel) {\n window.removeEventListener('scroll', onCancel);\n window.removeEventListener('wheel', onCancel);\n }\n };\n }, [cancelOnScrolling, onCancel]);\n\n // Disables window scrolling, if it is not opted-out.\n useEffect(() => {\n if (!dontDisableScrolling) {\n document.body.classList.add(S.scrollingDisabledByModal);\n }\n return () => {\n if (!dontDisableScrolling) {\n document.body.classList.remove(S.scrollingDisabledByModal);\n }\n };\n }, [dontDisableScrolling]);\n\n const focusLast = useMemo(() => (\n <div\n onFocus={() => {\n const elems = containerRef.current!.querySelectorAll('*');\n for (let i = elems.length - 1; i >= 0; --i) {\n (elems[i] as HTMLElement).focus();\n if (document.activeElement === elems[i]) return;\n }\n overlayRef.current?.focus();\n }}\n // TODO: Have a look at this later.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n />\n ), []);\n\n return createPortal(\n (\n <div>\n {focusLast}\n <div\n aria-label=\"Cancel\"\n className={theme.overlay}\n data-testid={\n process.env.NODE_ENV === 'production'\n ? undefined : testIdForOverlay\n }\n onClick={(e) => {\n if (onCancel) {\n onCancel();\n e.stopPropagation();\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Escape' && onCancel) {\n onCancel();\n e.stopPropagation();\n }\n }}\n ref={(node) => {\n if (node && node !== overlayRef.current) {\n overlayRef.current = node;\n node.focus();\n }\n }}\n role=\"button\"\n style={overlayStyle}\n tabIndex={0}\n />\n {\n // NOTE: These rules are disabled because our intention is to keep\n // the element non-interactive (thus not on the keyboard focus chain),\n // and it has `onClick` handler merely to stop propagation of click\n // events to its parent container. This is needed because, for example\n // when the modal is wrapped into an interactive element we don't want\n // any clicks inside the modal to bubble-up to that parent element\n // (because visually and logically the modal dialog does not belong\n // to its parent container, where it technically belongs from\n // the HTML mark-up perpective).\n }\n <div // eslint-disable-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions\n aria-modal=\"true\"\n className={theme.container}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n onClick={(e) => {\n e.stopPropagation();\n }}\n onWheel={(event) => {\n event.stopPropagation();\n }}\n ref={containerRef}\n role=\"dialog\"\n style={style ?? containerStyle}\n >\n {children}\n </div>\n <div\n onFocus={() => {\n overlayRef.current?.focus();\n }}\n // TODO: Have a look at this later.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n />\n {focusLast}\n </div>\n ),\n document.body,\n );\n};\n\nexport default themed(BaseModal, 'Modal', baseTheme);\n\n/* Non-themed version of the Modal. */\nexport { BaseModal };\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","names":["useEffect","useMemo","useRef","createPortal","themed","baseTheme","S","jsx","_jsx","jsxs","_jsxs","BaseModal","cancelOnScrolling","children","containerStyle","dontDisableScrolling","onCancel","overlayStyle","style","testId","testIdForOverlay","theme","containerRef","overlayRef","window","addEventListener","removeEventListener","document","body","classList","add","scrollingDisabledByModal","remove","focusLast","onFocus","elems","current","querySelectorAll","i","length","focus","activeElement","tabIndex","className","overlay","process","env","NODE_ENV","undefined","onClick","e","stopPropagation","onKeyDown","key","ref","node","role","container","onWheel","event"],"sources":["../../../../../src/shared/components/Modal/index.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type FunctionComponent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\n\nimport { createPortal } from 'react-dom';\nimport themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport baseTheme from './base-theme.scss';\nimport S from './styles.scss';\n\ntype PropsT = {\n cancelOnScrolling?: boolean;\n children?: ReactNode;\n dontDisableScrolling?: boolean;\n onCancel?: () => void;\n overlayStyle?: CSSProperties;\n style?: CSSProperties;\n testId?: string;\n testIdForOverlay?: string;\n theme: Theme<'container' | 'overlay'>;\n\n /** @deprecated */\n containerStyle?: CSSProperties;\n};\n\n/**\n * The `<Modal>` component implements a simple themeable modal window, wrapped\n * into the default theme. `<BaseModal>` exposes the base non-themed component.\n * **Children:** Component children are rendered as the modal content.\n * @param {object} props Component properties. Beside props documented below,\n * [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties) are supported as well.\n * @param {function} [props.onCancel] The callback to trigger when user\n * clicks outside the modal, or presses Escape. It is expected to hide the\n * modal.\n * @param {ModalTheme} [props.theme] _Ad hoc_ theme.\n */\nconst BaseModal: FunctionComponent<PropsT> = ({\n cancelOnScrolling,\n children,\n containerStyle,\n dontDisableScrolling,\n onCancel,\n overlayStyle,\n style,\n testId,\n testIdForOverlay,\n theme,\n}) => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const overlayRef = useRef<HTMLDivElement | null>(null);\n\n // Sets up modal cancellation of scrolling, if opted-in.\n useEffect(() => {\n if (cancelOnScrolling && onCancel) {\n window.addEventListener('scroll', onCancel);\n window.addEventListener('wheel', onCancel);\n }\n return () => {\n if (cancelOnScrolling && onCancel) {\n window.removeEventListener('scroll', onCancel);\n window.removeEventListener('wheel', onCancel);\n }\n };\n }, [cancelOnScrolling, onCancel]);\n\n // Disables window scrolling, if it is not opted-out.\n useEffect(() => {\n if (!dontDisableScrolling) {\n document.body.classList.add(S.scrollingDisabledByModal);\n }\n return () => {\n if (!dontDisableScrolling) {\n document.body.classList.remove(S.scrollingDisabledByModal);\n }\n };\n }, [dontDisableScrolling]);\n\n const focusLast = useMemo(() => (\n <div\n onFocus={() => {\n const elems = containerRef.current!.querySelectorAll('*');\n for (let i = elems.length - 1; i >= 0; --i) {\n (elems[i] as HTMLElement).focus();\n if (document.activeElement === elems[i]) return;\n }\n overlayRef.current?.focus();\n }}\n // TODO: Have a look at this later.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n />\n ), []);\n\n return createPortal(\n (\n <div>\n {focusLast}\n <div\n aria-label=\"Cancel\"\n className={theme.overlay}\n data-testid={\n process.env.NODE_ENV === 'production'\n ? undefined : testIdForOverlay\n }\n onClick={(e) => {\n if (onCancel) {\n onCancel();\n e.stopPropagation();\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Escape' && onCancel) {\n onCancel();\n e.stopPropagation();\n }\n }}\n ref={(node) => {\n if (node && node !== overlayRef.current) {\n overlayRef.current = node;\n node.focus();\n }\n }}\n role=\"button\"\n style={overlayStyle}\n tabIndex={0}\n />\n {\n // NOTE: These rules are disabled because our intention is to keep\n // the element non-interactive (thus not on the keyboard focus chain),\n // and it has `onClick` handler merely to stop propagation of click\n // events to its parent container. This is needed because, for example\n // when the modal is wrapped into an interactive element we don't want\n // any clicks inside the modal to bubble-up to that parent element\n // (because visually and logically the modal dialog does not belong\n // to its parent container, where it technically belongs from\n // the HTML mark-up perpective).\n }\n <div // eslint-disable-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions\n aria-modal=\"true\"\n className={theme.container}\n data-testid={process.env.NODE_ENV === 'production' ? undefined : testId}\n onClick={(e) => {\n e.stopPropagation();\n }}\n onWheel={(event) => {\n event.stopPropagation();\n }}\n ref={containerRef}\n role=\"dialog\"\n style={style ?? containerStyle}\n >\n {children}\n </div>\n <div\n onFocus={() => {\n overlayRef.current?.focus();\n }}\n // TODO: Have a look at this later.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n />\n {focusLast}\n </div>\n ),\n document.body,\n );\n};\n\nexport default /* #__PURE__ */ themed(BaseModal, 'Modal', baseTheme);\n\n/* Non-themed version of the Modal. */\nexport { BaseModal };\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -12,5 +12,5 @@ import themed from"@dr.pogodin/react-themes";const baseTheme={"context":"zv9tdn"
|
|
|
12
12
|
* @param {PageLayoutTheme} [props.theme] _Ad hoc_ theme.
|
|
13
13
|
* @param {...any} [props....]
|
|
14
14
|
* [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)
|
|
15
|
-
*/const PageLayout=({children,leftSidePanelContent,rightSidePanelContent,theme})=>/*#__PURE__*/_jsxs("div",{className:theme.container,children:[/*#__PURE__*/_jsx("div",{className:[theme.sidePanel,theme.leftSidePanel].join(" "),children:leftSidePanelContent}),/*#__PURE__*/_jsx("div",{className:theme.mainPanel,children:children}),/*#__PURE__*/_jsx("div",{className:[theme.sidePanel,theme.rightSidePanel].join(" "),children:rightSidePanelContent})]});export default themed(PageLayout,"PageLayout",baseTheme);
|
|
15
|
+
*/const PageLayout=({children,leftSidePanelContent,rightSidePanelContent,theme})=>/*#__PURE__*/_jsxs("div",{className:theme.container,children:[/*#__PURE__*/_jsx("div",{className:[theme.sidePanel,theme.leftSidePanel].join(" "),children:leftSidePanelContent}),/*#__PURE__*/_jsx("div",{className:theme.mainPanel,children:children}),/*#__PURE__*/_jsx("div",{className:[theme.sidePanel,theme.rightSidePanel].join(" "),children:rightSidePanelContent})]});export default/* #__PURE__ */themed(PageLayout,"PageLayout",baseTheme);
|
|
16
16
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["themed","baseTheme","jsx","_jsx","jsxs","_jsxs","PageLayout","children","leftSidePanelContent","rightSidePanelContent","theme","className","container","sidePanel","leftSidePanel","join","mainPanel","rightSidePanel"],"sources":["../../../../../src/shared/components/PageLayout/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport baseTheme from './base-theme.scss';\n\ntype ThemeKeyT = 'container' | 'leftSidePanel' | 'mainPanel' | 'rightSidePanel'\n | 'sidePanel';\n\ntype PropsT = {\n children?: ReactNode;\n leftSidePanelContent?: ReactNode;\n rightSidePanelContent?: ReactNode;\n theme: Theme<ThemeKeyT>;\n};\n\n/**\n * Simple and themeable page layout. It keeps the main content centered in\n * a column of limited width, which fills entire viewport on small screens\n * (under `$screen-md = 1024px` size). At larger screens the column keeps\n * `$screen-md` size, and it is centered at the page, surrounded by side\n * panels, where additional content can be displayed.\n *\n * **Children:** Component children are rendered as the content of main panel.\n * @param {object} [props] Component properties.\n * @param {Node} [props.leftSidePanelContent] The content for left side panel.\n * @param {Node} [props.rightSidePanelContent] The content for right side panel.\n * @param {PageLayoutTheme} [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 PageLayout: React.FunctionComponent<PropsT> = ({\n children,\n leftSidePanelContent,\n rightSidePanelContent,\n theme,\n}) => (\n <div className={theme.container}>\n <div className={[theme.sidePanel, theme.leftSidePanel].join(' ')}>\n {leftSidePanelContent}\n </div>\n <div className={theme.mainPanel}>\n {children}\n </div>\n <div className={[theme.sidePanel, theme.rightSidePanel].join(' ')}>\n {rightSidePanelContent}\n </div>\n </div>\n);\n\nexport default themed(PageLayout, 'PageLayout', baseTheme);\n"],"mappings":"AAEA,MAAO,CAAAA,MAAM,KAAsB,0BAA0B,OAAAC,SAAA,mHAEnB,OAAAC,GAAA,IAAAC,IAAA,CAAAC,IAAA,IAAAC,KAAA,yBAY1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GACA,KAAM,CAAAC,UAA2C,CAAGA,CAAC,CACnDC,QAAQ,CACRC,oBAAoB,CACpBC,qBAAqB,CACrBC,KACF,CAAC,gBACCL,KAAA,QAAKM,SAAS,CAAED,KAAK,CAACE,SAAU,CAAAL,QAAA,eAC9BJ,IAAA,QAAKQ,SAAS,CAAE,CAACD,KAAK,CAACG,SAAS,CAAEH,KAAK,CAACI,aAAa,CAAC,CAACC,IAAI,CAAC,GAAG,CAAE,CAAAR,QAAA,CAC9DC,oBAAoB,CAClB,CAAC,cACNL,IAAA,QAAKQ,SAAS,CAAED,KAAK,CAACM,SAAU,CAAAT,QAAA,CAC7BA,QAAQ,CACN,CAAC,cACNJ,IAAA,QAAKQ,SAAS,CAAE,CAACD,KAAK,CAACG,SAAS,CAAEH,KAAK,CAACO,cAAc,CAAC,CAACF,IAAI,CAAC,GAAG,CAAE,CAAAR,QAAA,CAC/DE,qBAAqB,CACnB,CAAC,EACH,CACN,CAED,cAAe,
|
|
1
|
+
{"version":3,"file":"index.js","names":["themed","baseTheme","jsx","_jsx","jsxs","_jsxs","PageLayout","children","leftSidePanelContent","rightSidePanelContent","theme","className","container","sidePanel","leftSidePanel","join","mainPanel","rightSidePanel"],"sources":["../../../../../src/shared/components/PageLayout/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport themed, { type Theme } from '@dr.pogodin/react-themes';\n\nimport baseTheme from './base-theme.scss';\n\ntype ThemeKeyT = 'container' | 'leftSidePanel' | 'mainPanel' | 'rightSidePanel'\n | 'sidePanel';\n\ntype PropsT = {\n children?: ReactNode;\n leftSidePanelContent?: ReactNode;\n rightSidePanelContent?: ReactNode;\n theme: Theme<ThemeKeyT>;\n};\n\n/**\n * Simple and themeable page layout. It keeps the main content centered in\n * a column of limited width, which fills entire viewport on small screens\n * (under `$screen-md = 1024px` size). At larger screens the column keeps\n * `$screen-md` size, and it is centered at the page, surrounded by side\n * panels, where additional content can be displayed.\n *\n * **Children:** Component children are rendered as the content of main panel.\n * @param {object} [props] Component properties.\n * @param {Node} [props.leftSidePanelContent] The content for left side panel.\n * @param {Node} [props.rightSidePanelContent] The content for right side panel.\n * @param {PageLayoutTheme} [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 PageLayout: React.FunctionComponent<PropsT> = ({\n children,\n leftSidePanelContent,\n rightSidePanelContent,\n theme,\n}) => (\n <div className={theme.container}>\n <div className={[theme.sidePanel, theme.leftSidePanel].join(' ')}>\n {leftSidePanelContent}\n </div>\n <div className={theme.mainPanel}>\n {children}\n </div>\n <div className={[theme.sidePanel, theme.rightSidePanel].join(' ')}>\n {rightSidePanelContent}\n </div>\n </div>\n);\n\nexport default /* #__PURE__ */ themed(PageLayout, 'PageLayout', baseTheme);\n"],"mappings":"AAEA,MAAO,CAAAA,MAAM,KAAsB,0BAA0B,OAAAC,SAAA,mHAEnB,OAAAC,GAAA,IAAAC,IAAA,CAAAC,IAAA,IAAAC,KAAA,yBAY1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GACA,KAAM,CAAAC,UAA2C,CAAGA,CAAC,CACnDC,QAAQ,CACRC,oBAAoB,CACpBC,qBAAqB,CACrBC,KACF,CAAC,gBACCL,KAAA,QAAKM,SAAS,CAAED,KAAK,CAACE,SAAU,CAAAL,QAAA,eAC9BJ,IAAA,QAAKQ,SAAS,CAAE,CAACD,KAAK,CAACG,SAAS,CAAEH,KAAK,CAACI,aAAa,CAAC,CAACC,IAAI,CAAC,GAAG,CAAE,CAAAR,QAAA,CAC9DC,oBAAoB,CAClB,CAAC,cACNL,IAAA,QAAKQ,SAAS,CAAED,KAAK,CAACM,SAAU,CAAAT,QAAA,CAC7BA,QAAQ,CACN,CAAC,cACNJ,IAAA,QAAKQ,SAAS,CAAE,CAACD,KAAK,CAACG,SAAS,CAAEH,KAAK,CAACO,cAAc,CAAC,CAACF,IAAI,CAAC,GAAG,CAAE,CAAAR,QAAA,CAC/DE,qBAAqB,CACnB,CAAC,EACH,CACN,CAED,cAAe,eAAgBT,MAAM,CAACM,UAAU,CAAE,YAAY,CAAEL,SAAS,CAAC","ignoreList":[]}
|
|
@@ -18,5 +18,5 @@ useLayoutEffect(()=>{const el=hiddenAreaRef.current;if(el)setHeight(el.scrollHei
|
|
|
18
18
|
,value:localValue||" "}),/*#__PURE__*/_jsx("textarea",{className:theme.textarea,"data-testid":process.env.NODE_ENV==="production"?undefined:testId,disabled:disabled,onBlur:onBlur// When value is "undefined" the text area is not-managed, and we should
|
|
19
19
|
// manage it internally for the measurement / resizing functionality
|
|
20
20
|
// to work.
|
|
21
|
-
,onChange:value===undefined?e=>{setLocalValue(e.target.value)}:onChange,onKeyDown:onKeyDown,placeholder:placeholder,ref:textAreaRef,style:{height},value:localValue}),error&&error!==true?/*#__PURE__*/_jsx("div",{className:theme.errorMessage,children:error}):null]})};export default themed(TextArea,"TextArea",defaultTheme);
|
|
21
|
+
,onChange:value===undefined?e=>{setLocalValue(e.target.value)}:onChange,onKeyDown:onKeyDown,placeholder:placeholder,ref:textAreaRef,style:{height},value:localValue}),error&&error!==true?/*#__PURE__*/_jsx("div",{className:theme.errorMessage,children:error}):null]})};export default/* #__PURE__ */themed(TextArea,"TextArea",defaultTheme);
|
|
22
22
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useEffect","useLayoutEffect","useRef","useState","themed","defaultTheme","jsx","_jsx","jsxs","_jsxs","TextArea","disabled","error","label","onBlur","onChange","onKeyDown","placeholder","testId","theme","value","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 themed, { type Theme } 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 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 = theme.container;\n if (error) containerClassName += ` ${theme.error}`;\n\n return (\n <div\n className={containerClassName}\n onFocus={() => {\n textAreaRef.current?.focus();\n }}\n >\n {label === undefined ? null : <div className={theme.label}>{label}</div>}\n <textarea\n className={`${theme.textarea} ${theme.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={theme.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={theme.errorMessage}>{error}</div>\n : null}\n </div>\n );\n};\n\nexport default themed(TextArea, 'TextArea', defaultTheme);\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","names":["useEffect","useLayoutEffect","useRef","useState","themed","defaultTheme","jsx","_jsx","jsxs","_jsxs","TextArea","disabled","error","label","onBlur","onChange","onKeyDown","placeholder","testId","theme","value","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 themed, { type Theme } 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 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 = theme.container;\n if (error) containerClassName += ` ${theme.error}`;\n\n return (\n <div\n className={containerClassName}\n onFocus={() => {\n textAreaRef.current?.focus();\n }}\n >\n {label === undefined ? null : <div className={theme.label}>{label}</div>}\n <textarea\n className={`${theme.textarea} ${theme.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={theme.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={theme.errorMessage}>{error}</div>\n : null}\n </div>\n );\n};\n\nexport default /* #__PURE__ */ themed(TextArea, 'TextArea', defaultTheme);\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,5 +6,5 @@ import themed from"@dr.pogodin/react-themes";const defaultTheme={"context":"eVCJ
|
|
|
6
6
|
* @param {ThrobberTheme} [props.theme] _Ad hoc_ theme.
|
|
7
7
|
* @param {...any} [props....]
|
|
8
8
|
* [Other theming properties](https://www.npmjs.com/package/@dr.pogodin/react-themes#themed-component-properties)
|
|
9
|
-
*/const Throbber=({theme})=>/*#__PURE__*/_jsxs("span",{className:theme.container,children:[/*#__PURE__*/_jsx("span",{className:theme.circle}),/*#__PURE__*/_jsx("span",{className:theme.circle}),/*#__PURE__*/_jsx("span",{className:theme.circle})]});export default themed(Throbber,"Throbber",defaultTheme);
|
|
9
|
+
*/const Throbber=({theme})=>/*#__PURE__*/_jsxs("span",{className:theme.container,children:[/*#__PURE__*/_jsx("span",{className:theme.circle}),/*#__PURE__*/_jsx("span",{className:theme.circle}),/*#__PURE__*/_jsx("span",{className:theme.circle})]});export default/* #__PURE__ */themed(Throbber,"Throbber",defaultTheme);
|
|
10
10
|
//# sourceMappingURL=index.js.map
|