@sima-land/ui-nucleons 40.3.0 → 41.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/_internal/body-scroll.d.ts +9 -0
  2. package/_internal/body-scroll.js +21 -1
  3. package/alert/index.js +1 -1
  4. package/arrow-button/index.d.ts +1 -0
  5. package/avatar/user.d.ts +1 -0
  6. package/card/index.d.ts +1 -0
  7. package/carousel/draggable.js +3 -1
  8. package/carousel/index.d.ts +2 -2
  9. package/carousel/index.js +1 -1
  10. package/chips/index.d.ts +5 -14
  11. package/chips/index.js +24 -9
  12. package/chips/item.d.ts +15 -0
  13. package/chips/item.js +20 -0
  14. package/constants.d.ts +6 -0
  15. package/constants.js +9 -0
  16. package/dot-nav/index.d.ts +1 -0
  17. package/hooks/index.d.ts +2 -1
  18. package/hooks/index.js +9 -7
  19. package/no-index-mark/index.d.ts +1 -0
  20. package/package.json +49 -51
  21. package/pagination/utils.d.ts +1 -1
  22. package/price/index.d.ts +1 -0
  23. package/rating/index.js +2 -2
  24. package/readme.md +6 -6
  25. package/screen/index.d.ts +12 -53
  26. package/screen/index.js +31 -85
  27. package/screen/screen.module.scss +16 -15
  28. package/screen/slots.d.ts +32 -0
  29. package/screen/slots.js +97 -0
  30. package/screen/utils.d.ts +13 -2
  31. package/screen/utils.js +3 -7
  32. package/side-page/index.d.ts +15 -2
  33. package/side-page/index.js +2 -2
  34. package/stroked-svg/index.d.ts +17 -0
  35. package/stroked-svg/index.js +52 -0
  36. package/stroked-svg/index.module.scss +17 -0
  37. package/super-ellipse-clip-path/index.d.ts +1 -0
  38. package/tabs/index.d.ts +32 -25
  39. package/tabs/index.js +30 -24
  40. package/tabs/tabs.module.scss +21 -19
  41. package/text-field/index.js +1 -1
  42. package/touch-slider/index.js +2 -1
  43. package/unknown-content/unknown-content.module.scss +3 -3
  44. package/screen/screen-layout.d.ts +0 -57
  45. package/screen/screen-layout.js +0 -116
package/screen/index.js CHANGED
@@ -1,97 +1,43 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
4
  };
21
5
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.takeScrollableElement = exports.setRefValue = exports.Screen = void 0;
23
- const react_1 = __importStar(require("react"));
24
- const portal_1 = require("../portal");
25
- const lodash_1 = require("lodash");
26
- const screen_layout_1 = require("./screen-layout");
27
- const utils_1 = require("./utils");
28
- const loading_overlay_1 = require("../loading-overlay");
29
- const body_scroll_lock_1 = require("body-scroll-lock");
6
+ exports.Screen = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const slots_1 = require("./slots");
30
9
  const layer_1 = require("../helpers/layer");
10
+ const define_slots_1 = require("../helpers/define-slots");
11
+ const utils_1 = require("./utils");
12
+ const screen_module_scss_1 = __importDefault(require("./screen.module.scss"));
31
13
  /**
32
14
  * Экран.
33
15
  * @param props Свойства.
34
16
  * @return Элемент.
35
17
  */
36
- const Screen = ({ children, contentRef, footer, fullScrollThreshold = 320, loading = false, loadingArea = 'full', loadingOverlayProps, navBarProps, onBack, onClose, onFullScroll, subtitle, title, withBackButton = false, withCloseButton = true, withDivideHeader = true, withHeader = true, inPortal = true, }) => {
37
- const Wrapper = inPortal ? portal_1.Portal : react_1.Fragment;
18
+ const Screen = ({ children, loading, loadingArea = 'full', loadingOverlayProps, onFullScroll, fullScrollThreshold = 320, 'data-testid': testId = 'screen', }) => {
19
+ const fullLoading = loading && loadingArea === 'full';
38
20
  const layer = (0, layer_1.useLayer)() + 300; // 300 из-за монолита
39
- const rootRef = (0, react_1.useRef)(null);
40
- const innerContentRef = (0, react_1.useRef)(null);
41
- // включаем прокрутку body при размонтировании
42
- (0, react_1.useEffect)(() => () => {
43
- innerContentRef.current && (0, body_scroll_lock_1.enableBodyScroll)(innerContentRef.current);
44
- }, []);
45
- return (react_1.default.createElement(Wrapper, null,
46
- react_1.default.createElement("div", { ref: rootRef, className: (0, utils_1.cx)('screen', 'full-width'), style: { zIndex: layer } }, loading && loadingArea === 'full' ? (react_1.default.createElement(loading_overlay_1.LoadingOverlay, Object.assign({}, loadingOverlayProps))) : (react_1.default.createElement(layer_1.LayerProvider, { value: layer },
47
- react_1.default.createElement(screen_layout_1.ScreenLayout, { title: title, subtitle: subtitle, withHeader: withHeader, withDivideHeader: withDivideHeader, withBackButton: withBackButton, withCloseButton: withCloseButton, children: loading && loadingArea === 'content' ? (react_1.default.createElement(loading_overlay_1.LoadingOverlay, Object.assign({}, loadingOverlayProps, (loadingArea === 'content' && {
48
- fill: false,
49
- style: { height: '100%' },
50
- })))) : (children), childrenRef: element => {
51
- (0, exports.setRefValue)(contentRef, element);
52
- (0, exports.takeScrollableElement)(innerContentRef, element);
53
- }, footer: footer, onBack: ({ contentElement }) => {
54
- onBack &&
55
- onBack({
56
- rootElement: rootRef.current,
57
- contentElement,
58
- });
59
- }, onClose: ({ contentElement }) => {
60
- onClose &&
61
- onClose({
62
- rootElement: rootRef.current,
63
- contentElement,
64
- });
65
- }, onFullScroll: onFullScroll, fullScrollThreshold: fullScrollThreshold, navBarProps: navBarProps }))))));
66
- };
67
- exports.Screen = Screen;
68
- /**
69
- * Записывает переданное значение в ref контента.
70
- * @param ref Ref-контейнер.
71
- * @param value Значение для записи.
72
- */
73
- const setRefValue = (ref, value) => {
74
- if ((0, lodash_1.isFunction)(ref)) {
75
- ref(value);
76
- }
77
- else if (ref) {
78
- ref.current = value;
79
- }
80
- };
81
- exports.setRefValue = setRefValue;
82
- /**
83
- * Записывает полученный элемент в ref и отключает прокрутку.
84
- * @param ref Ref-контейнер.
85
- * @param element Элемент для записи.
86
- */
87
- const takeScrollableElement = (ref, element) => {
88
- if (element && element !== ref.current) {
89
- // если элемент изменился - включаем прокрутку для старого
90
- ref.current && (0, body_scroll_lock_1.enableBodyScroll)(ref.current);
91
- // сохраняем новый элемент
92
- ref.current = element;
93
- // отключаем прокрутку для нового элемента
94
- (0, body_scroll_lock_1.disableBodyScroll)(element);
21
+ const { header, body, footer } = (0, define_slots_1.defineSlots)(children, {
22
+ header: slots_1.HeaderSlot,
23
+ body: slots_1.BodySlot,
24
+ footer: slots_1.FooterSlot,
25
+ });
26
+ if (!body) {
27
+ throw Error('Looks like you are trying to render <Screen /> without <Screen.Body /> slot, but it is required');
95
28
  }
29
+ return (react_1.default.createElement("div", { className: screen_module_scss_1.default.root, style: { zIndex: layer }, "data-testid": testId },
30
+ react_1.default.createElement(layer_1.LayerProvider, { value: layer },
31
+ !fullLoading && header,
32
+ react_1.default.createElement(utils_1.ScreenContext.Provider, { value: {
33
+ loading,
34
+ loadingOverlayProps,
35
+ onFullScroll,
36
+ fullScrollThreshold,
37
+ } }, body),
38
+ !fullLoading && footer && (react_1.default.createElement("div", { className: screen_module_scss_1.default.footer, "data-testid": 'screen:footer' }, footer)))));
96
39
  };
97
- exports.takeScrollableElement = takeScrollableElement;
40
+ exports.Screen = Screen;
41
+ exports.Screen.Header = slots_1.HeaderSlot;
42
+ exports.Screen.Body = slots_1.BodySlot;
43
+ exports.Screen.Footer = slots_1.FooterSlot;
@@ -1,4 +1,4 @@
1
- .screen {
1
+ .root {
2
2
  position: fixed;
3
3
 
4
4
  // для корректного отображения с динамическим viewport переменная --offsetTop должна быть доступна
@@ -9,24 +9,25 @@
9
9
 
10
10
  // для корректного отображения с динамическим viewport переменная --vh должна быть доступна
11
11
  height: calc(var(--vh, 1vh) * 100);
12
+ width: 100%;
12
13
  box-sizing: border-box;
13
14
  background-color: #fff;
14
15
  outline: 100px solid #fff;
15
- .content {
16
- height: 0;
17
- overflow-y: auto;
18
- flex-grow: 1;
19
- flex-shrink: 0;
20
- -webkit-overflow-scrolling: touch;
21
- }
22
- .footer {
23
- min-height: 56px;
24
- flex-grow: 0;
25
- flex-shrink: 0;
26
- box-shadow: inset 0 1px 0 #e0e0e0;
27
- }
28
16
  }
29
17
 
30
- .full-width {
18
+ .body {
19
+ width: 100%;
20
+ height: 0;
21
+ overflow-y: auto;
22
+ flex-grow: 1;
23
+ flex-shrink: 0;
24
+ -webkit-overflow-scrolling: touch;
25
+ }
26
+
27
+ .footer {
28
+ min-height: 56px;
31
29
  width: 100%;
30
+ flex-grow: 0;
31
+ flex-shrink: 0;
32
+ box-shadow: inset 0 1px 0 #e0e0e0;
32
33
  }
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { NavBarProps } from '../nav-bar';
3
+ export interface HeaderSlotProps extends NavBarProps {
4
+ /** Нужна ли разделительная полоса внизу шапки экрана. */
5
+ divided?: boolean;
6
+ /** Заголовок. */
7
+ title?: string;
8
+ /** Подзаголовок. */
9
+ subtitle?: string;
10
+ /** Будет вызвана при нажатии на кнопку-стрелку. */
11
+ onBack?: () => void;
12
+ /** Будет вызвана при нажатии на кнопку-крести. */
13
+ onClose?: () => void;
14
+ }
15
+ /**
16
+ * Слот шапки экрана.
17
+ * @param props Свойства.
18
+ * @return Элемент.
19
+ */
20
+ export declare const HeaderSlot: ({ divided, title, subtitle, buttons, onBack, onClose, ...restProps }: HeaderSlotProps) => JSX.Element;
21
+ /**
22
+ * Слот основного контента экрана.
23
+ */
24
+ export declare const BodySlot: React.ForwardRefExoticComponent<{
25
+ children?: React.ReactNode;
26
+ } & React.RefAttributes<HTMLDivElement | null>>;
27
+ /**
28
+ * Слот футера экрана.
29
+ * @param props Свойства.
30
+ * @return Элемент.
31
+ */
32
+ export declare const FooterSlot: React.FC;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __rest = (this && this.__rest) || function (s, e) {
22
+ var t = {};
23
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
24
+ t[p] = s[p];
25
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
26
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
27
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
28
+ t[p[i]] = s[p[i]];
29
+ }
30
+ return t;
31
+ };
32
+ var __importDefault = (this && this.__importDefault) || function (mod) {
33
+ return (mod && mod.__esModule) ? mod : { "default": mod };
34
+ };
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FooterSlot = exports.BodySlot = exports.HeaderSlot = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const nav_bar_1 = require("../nav-bar");
39
+ const lodash_1 = require("lodash");
40
+ const arrow_left_1 = __importDefault(require("@sima-land/ui-quarks/icons/24x24/Stroked/arrow-left"));
41
+ const cross_1 = __importDefault(require("@sima-land/ui-quarks/icons/24x24/Stroked/cross"));
42
+ const body_scroll_1 = require("../_internal/body-scroll");
43
+ const hooks_1 = require("../hooks");
44
+ const loading_overlay_1 = require("../loading-overlay");
45
+ const utils_1 = require("./utils");
46
+ const screen_module_scss_1 = __importDefault(require("./screen.module.scss"));
47
+ /**
48
+ * Слот шапки экрана.
49
+ * @param props Свойства.
50
+ * @return Элемент.
51
+ */
52
+ const HeaderSlot = (_a) => {
53
+ var { divided, title, subtitle, buttons, onBack, onClose } = _a, restProps = __rest(_a, ["divided", "title", "subtitle", "buttons", "onBack", "onClose"]);
54
+ return (react_1.default.createElement(nav_bar_1.NavBar, Object.assign({}, restProps, { title: title, subtitle: subtitle, bottomBordered: divided, buttons: Object.assign(Object.assign({}, buttons), { start: onBack
55
+ ? {
56
+ // ВАЖНО: не подмешиваем свойства из buttons.start
57
+ // чтобы не распылять конфигурацию одной и той же кнопки по нескольким местам
58
+ icon: arrow_left_1.default,
59
+ onClick: onBack,
60
+ 'aria-label': 'Вернуться назад',
61
+ 'data-testid': 'screen:back',
62
+ }
63
+ : (0, lodash_1.get)(buttons, 'start'), end: onClose
64
+ ? {
65
+ // ВАЖНО: не подмешиваем свойства из buttons.end
66
+ // чтобы не распылять конфигурацию одной и той же кнопки по нескольким местам
67
+ icon: cross_1.default,
68
+ onClick: onClose,
69
+ 'aria-label': `Закрыть ${title || ''}`.trim(),
70
+ 'data-testid': 'screen:close',
71
+ }
72
+ : (0, lodash_1.get)(buttons, 'end') }) })));
73
+ };
74
+ exports.HeaderSlot = HeaderSlot;
75
+ /**
76
+ * Слот основного контента экрана.
77
+ */
78
+ exports.BodySlot = (0, react_1.forwardRef)(function BodySlot({ children }, outerRef) {
79
+ const { loading, loadingOverlayProps, onFullScroll, fullScrollThreshold } = (0, react_1.useContext)(utils_1.ScreenContext);
80
+ // при блокировке прокрутки нужно передавать элемент, которому нужно сохранить возможность прокрутки
81
+ // https://github.com/willmcpo/body-scroll-lock/blame/79c4cf2c956eb7d5cf8d54a03d12751bc6ac8aa3/README.md#L52
82
+ // поэтому используем внутренний ref и useImperativeHandle
83
+ const ref = (0, react_1.useRef)(null);
84
+ (0, react_1.useImperativeHandle)(outerRef, () => ref.current);
85
+ (0, body_scroll_1.useBodyScrollLock)(ref, true, { allowTouchMove: body_scroll_1.allowTouchMove });
86
+ (0, hooks_1.useInfiniteScroll)(ref, { onFullScroll, threshold: fullScrollThreshold });
87
+ return (
88
+ // ВАЖНО: элемент с ref должен выводиться всегда (без условий), т.к. он нужен для блокировки прокрутки
89
+ react_1.default.createElement("div", { ref: ref, className: screen_module_scss_1.default.body, "data-testid": 'screen:body' }, loading ? (react_1.default.createElement(loading_overlay_1.LoadingOverlay, Object.assign({}, loadingOverlayProps, { fill: false, style: { height: '100%' } }))) : (children)));
90
+ });
91
+ /**
92
+ * Слот футера экрана.
93
+ * @param props Свойства.
94
+ * @return Элемент.
95
+ */
96
+ const FooterSlot = ({ children }) => react_1.default.createElement(react_1.default.Fragment, null, children);
97
+ exports.FooterSlot = FooterSlot;
package/screen/utils.d.ts CHANGED
@@ -1,2 +1,13 @@
1
- export declare type OrNil<T> = T | null | undefined;
2
- export declare const cx: import("classnames/types").ClassNamesFn;
1
+ /// <reference types="react" />
2
+ import { LoadingOverlayProps } from '../loading-overlay';
3
+ export interface ScreenInnerProps {
4
+ /** Нужно ли выводить вместо содержимого состояние загрузки. */
5
+ loading?: boolean;
6
+ /** Свойства компонента LoadingOverlay. */
7
+ loadingOverlayProps?: LoadingOverlayProps;
8
+ /** Будет вызвана при полной прокрутке содержимого экрана. */
9
+ onFullScroll?: () => void;
10
+ /** Отступ от нижней границы содержимого экрана, после которого начинает срабатывать onFullScroll. */
11
+ fullScrollThreshold?: number;
12
+ }
13
+ export declare const ScreenContext: import("react").Context<ScreenInnerProps>;
package/screen/utils.js CHANGED
@@ -1,9 +1,5 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.cx = void 0;
7
- const bind_1 = __importDefault(require("classnames/bind"));
8
- const screen_module_scss_1 = __importDefault(require("./screen.module.scss"));
9
- exports.cx = bind_1.default.bind(screen_module_scss_1.default);
3
+ exports.ScreenContext = void 0;
4
+ const react_1 = require("react");
5
+ exports.ScreenContext = (0, react_1.createContext)({});
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { WithBodyScrollLock } from '../_internal/body-scroll';
3
+ import { CSSTransitionProps } from 'react-transition-group/CSSTransition';
3
4
  export interface SidePageProps extends WithBodyScrollLock {
4
5
  /** Нужно ли показать компонент. */
5
6
  shown?: boolean;
@@ -11,6 +12,18 @@ export interface SidePageProps extends WithBodyScrollLock {
11
12
  children?: React.ReactNode;
12
13
  /** Сработает при закрытии. */
13
14
  onClose?: () => void;
15
+ /** Обработчик "onEntering" для CSSTransition. */
16
+ onEntering?: CSSTransitionProps['onEntering'];
17
+ /** Обработчик "onEnter" для CSSTransition. */
18
+ onEnter?: CSSTransitionProps['onEnter'];
19
+ /** Обработчик "onEntered" для CSSTransition. */
20
+ onEntered?: CSSTransitionProps['onEntered'];
21
+ /** Обработчик "onExiting" для CSSTransition. */
22
+ onExiting?: CSSTransitionProps['onExiting'];
23
+ /** Обработчик "onExited" для CSSTransition. */
24
+ onExited?: CSSTransitionProps['onExited'];
25
+ /** Обработчик "onExit" для CSSTransition. */
26
+ onExit?: CSSTransitionProps['onExit'];
14
27
  }
15
28
  /**
16
29
  * Компонент модального окна, прикрепленного к правой стороне экрана.
@@ -18,7 +31,7 @@ export interface SidePageProps extends WithBodyScrollLock {
18
31
  * @return Элемент.
19
32
  */
20
33
  export declare const SidePage: {
21
- ({ shown, withTransitions, ...restProps }: SidePageProps): JSX.Element;
34
+ ({ shown, withTransitions, onEnter, onEntering, onEntered, onExit, onExiting, onExited, ...restProps }: SidePageProps): JSX.Element;
22
35
  Header: {
23
36
  ({ onBack, onClose, ...topBarProps }: import("../top-bar").TopBarProps & {
24
37
  onBack?: (() => void) | undefined;
@@ -28,7 +41,7 @@ export declare const SidePage: {
28
41
  };
29
42
  Body: {
30
43
  ({ children }: {
31
- children?: React.ReactNode;
44
+ children?: React.ReactNode; /** Обработчик "onExiting" для CSSTransition. */
32
45
  }): JSX.Element;
33
46
  displayName: string;
34
47
  };
@@ -56,9 +56,9 @@ const transitionClasses = {
56
56
  * @return Элемент.
57
57
  */
58
58
  const SidePage = (_a) => {
59
- var { shown, withTransitions } = _a, restProps = __rest(_a, ["shown", "withTransitions"]);
59
+ var { shown, withTransitions, onEnter, onEntering, onEntered, onExit, onExiting, onExited } = _a, restProps = __rest(_a, ["shown", "withTransitions", "onEnter", "onEntering", "onEntered", "onExit", "onExiting", "onExited"]);
60
60
  const transitionDuration = withTransitions ? 300 : 0;
61
- return (react_1.default.createElement(CSSTransition_1.default, { in: shown, timeout: transitionDuration, classNames: transitionClasses, unmountOnExit: true }, transitionStatus => (react_1.default.createElement(SidePageInner, Object.assign({}, restProps, { transitionStatus, transitionDuration })))));
61
+ return (react_1.default.createElement(CSSTransition_1.default, { in: shown, timeout: transitionDuration, classNames: transitionClasses, unmountOnExit: true, onEntering: onEntering, onEnter: onEnter, onEntered: onEntered, onExit: onExit, onExiting: onExiting, onExited: onExited }, transitionStatus => (react_1.default.createElement(SidePageInner, Object.assign({}, restProps, { transitionStatus, transitionDuration })))));
62
62
  };
63
63
  exports.SidePage = SidePage;
64
64
  /**
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ export interface StrokedSVGProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
3
+ /** Компонент, выводящий svg-элемент. */
4
+ component: React.ComponentType<React.SVGAttributes<SVGSVGElement>>;
5
+ /** Ширина внешней обводки. */
6
+ stroke?: string;
7
+ /** Цвет внешней обводки. */
8
+ strokeWidth?: number;
9
+ /** Цвет заливки. */
10
+ fill?: string;
11
+ }
12
+ /**
13
+ * Выводит иконку с внешней обводкой.
14
+ * @param props Свойства.
15
+ * @return Элемент.
16
+ */
17
+ export declare const StrokedSVG: React.ForwardRefExoticComponent<StrokedSVGProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __rest = (this && this.__rest) || function (s, e) {
22
+ var t = {};
23
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
24
+ t[p] = s[p];
25
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
26
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
27
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
28
+ t[p[i]] = s[p[i]];
29
+ }
30
+ return t;
31
+ };
32
+ var __importDefault = (this && this.__importDefault) || function (mod) {
33
+ return (mod && mod.__esModule) ? mod : { "default": mod };
34
+ };
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.StrokedSVG = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const colors_1 = require("../colors");
39
+ const classnames_1 = __importDefault(require("classnames"));
40
+ const index_module_scss_1 = __importDefault(require("./index.module.scss"));
41
+ /**
42
+ * Выводит иконку с внешней обводкой.
43
+ * @param props Свойства.
44
+ * @return Элемент.
45
+ */
46
+ exports.StrokedSVG = (0, react_1.forwardRef)((_a, ref) => {
47
+ var { component: Tag, fill, stroke = colors_1.COLORS.get('gray4'), strokeWidth = 1, className } = _a, restProps = __rest(_a, ["component", "fill", "stroke", "strokeWidth", "className"]);
48
+ return (react_1.default.createElement("div", Object.assign({ ref: ref, className: (0, classnames_1.default)(index_module_scss_1.default.root, className) }, restProps),
49
+ react_1.default.createElement(Tag, { stroke: stroke, strokeWidth: `${strokeWidth * 2}px`, className: index_module_scss_1.default.stroke }),
50
+ react_1.default.createElement(Tag, { fill: fill, className: index_module_scss_1.default.svg })));
51
+ });
52
+ exports.StrokedSVG.displayName = 'StrokedSVG';
@@ -0,0 +1,17 @@
1
+ .root {
2
+ display: inline-flex;
3
+ position: relative;
4
+ }
5
+
6
+ .stroke {
7
+ overflow: visible;
8
+ display: block;
9
+ position: absolute;
10
+ top: 0;
11
+ left: 0;
12
+ }
13
+
14
+ .svg {
15
+ display: block;
16
+ position: relative;
17
+ }
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export interface SuperEllipseClipPathProps {
2
3
  /** Идентификатор. */
3
4
  id?: string;
package/tabs/index.d.ts CHANGED
@@ -1,29 +1,36 @@
1
- /**
2
- * Компонент списка табов.
3
- * @param props Свойства компонента.
4
- * @param props.items Список табов.
5
- * @param props.getItemName Функция получения имени для отрисовки элемента.
6
- * @param props.onSelectItem Функция, вызываемая при выборе элемента списка.
7
- * @param props.isSelectedItem Функция, определяющая, является ли элемент выбранным.
8
- * @param props.isDisabledItem Функция, определяющая, является ли элемент невыбираемым.
9
- * @param props.type Тип таба.
10
- * @param props.underline Нужно ли подчеркивание группы табов.
11
- * @param props.stretch Необходимо ли растягивать табы под размер контейнера.
12
- * @param props.gapSize Размер отступа между табами.
13
- * @param props.className Внешние классы.
14
- * @return Элемент.
15
- */
16
- export declare function Tabs<T = any>({ items, getItemName, onSelectItem, isSelectedItem, isDisabledItem, view, underline, stretch, gapSize, className, 'data-testid': dataTestId, }: {
17
- items?: T[];
18
- } & {
19
- getItemName?: (i: T) => string;
20
- onSelectItem?: (i: T) => void;
21
- isSelectedItem?: (i: T) => boolean | undefined;
22
- isDisabledItem?: (i: T) => boolean | undefined;
23
- view?: 'clean' | 'round';
24
- underline?: boolean;
1
+ import React from 'react';
2
+ export interface TabsProps {
3
+ /** Визуальный вариант вкладок. */
4
+ view?: 'clean' | 'clean-underline' | 'round';
5
+ /** Необходимо ли растягивать вкладки под размер контейнера. */
25
6
  stretch?: boolean;
7
+ /** Размер отступа между вкладками. */
26
8
  gapSize?: 's' | 'm';
9
+ /** Внешние классы. */
27
10
  className?: string;
11
+ /** Вкладки. */
12
+ children?: React.ReactNode;
13
+ /** Идентификатор для систем автоматизированного тестирования. */
14
+ 'data-testid'?: string;
15
+ }
16
+ export interface TabsItemProps {
17
+ /** Название вкладки. */
18
+ name: string;
19
+ /** Выбрана ли вкладка. */
20
+ selected?: boolean;
21
+ /** Отключена ли вкладка. */
22
+ disabled?: boolean;
23
+ /** Идентификатор для систем автоматизированного тестирования. */
28
24
  'data-testid'?: string;
29
- }): JSX.Element;
25
+ /** Обработчик клика. */
26
+ onClick?: React.MouseEventHandler<HTMLLIElement>;
27
+ }
28
+ /**
29
+ * Компонент строки вкладок.
30
+ * @param props Свойства.
31
+ * @return Элемент.
32
+ */
33
+ export declare const Tabs: {
34
+ ({ children, view, stretch, gapSize, className, "data-testid": testId, }: TabsProps): JSX.Element;
35
+ Item: ({ name, selected, disabled, "data-testid": testId, onClick, }: TabsItemProps) => JSX.Element;
36
+ };
package/tabs/index.js CHANGED
@@ -1,37 +1,43 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
2
21
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
23
  };
5
24
  Object.defineProperty(exports, "__esModule", { value: true });
6
25
  exports.Tabs = void 0;
7
- const react_1 = __importDefault(require("react"));
26
+ const react_1 = __importStar(require("react"));
8
27
  const bind_1 = __importDefault(require("classnames/bind"));
9
- const lodash_1 = require("lodash");
10
- const fp_1 = require("lodash/fp");
11
28
  const tabs_module_scss_1 = __importDefault(require("./tabs.module.scss"));
12
29
  const cx = bind_1.default.bind(tabs_module_scss_1.default);
13
30
  /**
14
- * Компонент списка табов.
15
- * @param props Свойства компонента.
16
- * @param props.items Список табов.
17
- * @param props.getItemName Функция получения имени для отрисовки элемента.
18
- * @param props.onSelectItem Функция, вызываемая при выборе элемента списка.
19
- * @param props.isSelectedItem Функция, определяющая, является ли элемент выбранным.
20
- * @param props.isDisabledItem Функция, определяющая, является ли элемент невыбираемым.
21
- * @param props.type Тип таба.
22
- * @param props.underline Нужно ли подчеркивание группы табов.
23
- * @param props.stretch Необходимо ли растягивать табы под размер контейнера.
24
- * @param props.gapSize Размер отступа между табами.
25
- * @param props.className Внешние классы.
31
+ * Вкладка.
32
+ * @param props Свойства.
33
+ * @return Элемент.
34
+ */
35
+ const Tab = ({ name, selected, disabled, 'data-testid': testId = 'tab', onClick, }) => (react_1.default.createElement("li", { className: cx('item', { selected, disabled }), "data-testid": testId, onClick: disabled ? undefined : onClick }, String(name)));
36
+ /**
37
+ * Компонент строки вкладок.
38
+ * @param props Свойства.
26
39
  * @return Элемент.
27
40
  */
28
- function Tabs({ items, getItemName = lodash_1.identity, onSelectItem, isSelectedItem = (0, fp_1.prop)('active'), isDisabledItem = (0, fp_1.prop)('disabled'), view = 'clean', underline = false, stretch = false, gapSize = 'm', className, 'data-testid': dataTestId = 'tabs', }) {
29
- return (react_1.default.createElement("ul", { "data-testid": dataTestId, className: cx('root', `view-${view}`, `gap-${gapSize}`, {
30
- underline,
31
- stretch,
32
- }, className) }, items === null || items === void 0 ? void 0 : items.map((item, index) => (react_1.default.createElement("li", { key: index, onClick: () => onSelectItem === null || onSelectItem === void 0 ? void 0 : onSelectItem(item), className: cx('tab-item', {
33
- selected: isSelectedItem(item),
34
- disabled: isDisabledItem(item),
35
- }), "data-testid": 'tab' }, getItemName(item))))));
36
- }
41
+ const Tabs = ({ children, view = 'clean', stretch = false, gapSize = 'm', className, 'data-testid': testId = 'tabs', }) => (react_1.default.createElement("ul", { "data-testid": testId, className: cx('root', `view-${view}`, `gap-${gapSize}`, { stretch }, className) }, react_1.Children.toArray(children).filter(child => (0, react_1.isValidElement)(child) && child.type === Tab)));
37
42
  exports.Tabs = Tabs;
43
+ exports.Tabs.Item = Tab;