@alfalab/core-components-tab-bar 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/Component.d.ts +7 -0
  2. package/Component.js +39 -0
  3. package/components/tab/Component.d.ts +5 -0
  4. package/components/tab/Component.js +39 -0
  5. package/components/tab/index.css +71 -0
  6. package/components/tab/index.d.ts +1 -0
  7. package/components/tab/index.js +14 -0
  8. package/cssm/Component.d.ts +7 -0
  9. package/cssm/Component.js +39 -0
  10. package/cssm/components/tab/Component.d.ts +5 -0
  11. package/cssm/components/tab/Component.js +38 -0
  12. package/cssm/components/tab/index.d.ts +1 -0
  13. package/cssm/components/tab/index.js +15 -0
  14. package/cssm/components/tab/index.module.css +70 -0
  15. package/cssm/index.d.ts +2 -0
  16. package/cssm/index.js +18 -0
  17. package/cssm/index.module.css +29 -0
  18. package/cssm/types.d.ts +99 -0
  19. package/cssm/types.js +2 -0
  20. package/esm/Component.d.ts +7 -0
  21. package/esm/Component.js +30 -0
  22. package/esm/components/tab/Component.d.ts +5 -0
  23. package/esm/components/tab/Component.js +30 -0
  24. package/esm/components/tab/index.css +71 -0
  25. package/esm/components/tab/index.d.ts +1 -0
  26. package/esm/components/tab/index.js +6 -0
  27. package/esm/index.css +30 -0
  28. package/esm/index.d.ts +2 -0
  29. package/esm/index.js +8 -0
  30. package/esm/types.d.ts +99 -0
  31. package/esm/types.js +1 -0
  32. package/index.css +30 -0
  33. package/index.d.ts +2 -0
  34. package/index.js +16 -0
  35. package/modern/Component.d.ts +7 -0
  36. package/modern/Component.js +25 -0
  37. package/modern/components/tab/Component.d.ts +5 -0
  38. package/modern/components/tab/Component.js +27 -0
  39. package/modern/components/tab/index.css +71 -0
  40. package/modern/components/tab/index.d.ts +1 -0
  41. package/modern/components/tab/index.js +5 -0
  42. package/modern/index.css +30 -0
  43. package/modern/index.d.ts +2 -0
  44. package/modern/index.js +7 -0
  45. package/modern/types.d.ts +99 -0
  46. package/modern/types.js +1 -0
  47. package/package.json +24 -0
  48. package/src/Component.tsx +50 -0
  49. package/src/components/tab/Component.tsx +93 -0
  50. package/src/components/tab/index.module.css +45 -0
  51. package/src/components/tab/index.ts +1 -0
  52. package/src/index.module.css +16 -0
  53. package/src/index.ts +2 -0
  54. package/src/types.ts +139 -0
  55. package/types.d.ts +99 -0
  56. package/types.js +2 -0
@@ -0,0 +1,71 @@
1
+ /* hash: 8qv7e */
2
+ :root {
3
+ } /* deprecated */ :root {
4
+ --color-light-accent-primary: #ef3124;
5
+ --color-light-neutral-translucent-700: rgba(4, 4, 21, 0.47);
6
+ --color-light-text-secondary: rgba(4, 4, 19, 0.55); /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
7
+ } :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
8
+ } :root {
9
+ } :root {
10
+
11
+ /* Hard */
12
+
13
+ /* Up */
14
+
15
+ /* Hard up */
16
+ } :root {
17
+ } :root {
18
+ --gap-2xs: 4px;
19
+ --gap-xs: 8px;
20
+ } :root {
21
+ } :root {
22
+ } .tab-bar__component_1cyxn {
23
+ box-sizing: border-box;
24
+ background-color: transparent;
25
+ -webkit-tap-highlight-color: transparent;
26
+ outline: none;
27
+ border: 0;
28
+ margin: 0;
29
+ box-shadow: none;
30
+ border-radius: 0;
31
+ -webkit-user-select: none;
32
+ user-select: none;
33
+ vertical-align: middle;
34
+ appearance: none;
35
+ text-decoration: none;
36
+ min-width: 0;
37
+ cursor: pointer;
38
+
39
+ position: relative;
40
+ display: inline-flex;
41
+ flex-direction: column;
42
+ flex: 1 0 0;
43
+ align-items: center;
44
+ padding: var(--gap-xs) 0;
45
+ color: var(--color-light-neutral-translucent-700);
46
+ } .tab-bar__selected_1cyxn {
47
+ color: var(--color-light-accent-primary);
48
+ } .tab-bar__icon_1cyxn {
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ flex-grow: 1;
53
+ width: 100%;
54
+ } .tab-bar__label_1cyxn {
55
+ -webkit-line-clamp: 1;
56
+ display: -webkit-box;
57
+ -webkit-box-orient: vertical;
58
+ overflow: hidden;
59
+ word-break: break-all;
60
+ flex-shrink: 0;
61
+
62
+ color: var(--color-light-text-secondary);
63
+ } .tab-bar__labelSelected_1cyxn {
64
+ color: inherit;
65
+ } .tab-bar__indicator_1cyxn {
66
+ position: absolute;
67
+ top: var(--gap-2xs);
68
+ left: calc(50% + var(--gap-2xs));
69
+ height: 16px;
70
+ min-width: 16px;
71
+ }
@@ -0,0 +1 @@
1
+ export * from "./Component";
@@ -0,0 +1,6 @@
1
+ export { Tab } from './Component.js';
2
+ import 'tslib';
3
+ import 'react';
4
+ import 'classnames';
5
+ import '@alfalab/core-components-badge/esm';
6
+ import '@alfalab/core-components-typography/esm';
package/esm/index.css ADDED
@@ -0,0 +1,30 @@
1
+ /* hash: 1ycka */
2
+ :root {
3
+ } /* deprecated */ :root {
4
+ --color-light-base-bg-primary: #fff;
5
+ --color-light-neutral-300: #e7e8eb; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
6
+ } :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
7
+ } :root {
8
+ } :root {
9
+
10
+ /* Hard */
11
+
12
+ /* Up */
13
+
14
+ /* Hard up */
15
+ } :root {
16
+ } :root {
17
+ } :root {
18
+ } :root {
19
+ } .tab-bar__component_1tqhl {
20
+ display: flex;
21
+ justify-content: center;
22
+ height: 64px;
23
+ max-height: 64px;
24
+ background-color: var(--color-light-base-bg-primary);
25
+ box-sizing: border-box;
26
+ overflow: hidden;
27
+ transition: box-shadow 0.2s ease;
28
+ } .tab-bar__border_1tqhl {
29
+ box-shadow: 0 -1px 0 0 var(--color-light-neutral-300);
30
+ }
package/esm/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { TabBar } from "./Component";
2
+ export { TabBarProps, TabProps } from "./types";
package/esm/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { TabBar } from './Component.js';
2
+ import 'tslib';
3
+ import 'react';
4
+ import 'classnames';
5
+ import '@alfalab/core-components-shared/esm';
6
+ import './components/tab/Component.js';
7
+ import '@alfalab/core-components-badge/esm';
8
+ import '@alfalab/core-components-typography/esm';
package/esm/types.d.ts ADDED
@@ -0,0 +1,99 @@
1
+ import { AllHTMLAttributes, ElementType, ForwardRefExoticComponent, HTMLAttributes, ReactElement, ReactNode, RefAttributes } from 'react';
2
+ import { BadgeProps } from "@alfalab/core-components-badge";
3
+ type TabElementType = ReactElement<TabProps, ForwardRefExoticComponent<TabProps & RefAttributes<HTMLElement>>>;
4
+ interface TabBarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
5
+ /**
6
+ * Дополнительный класс
7
+ */
8
+ className?: string;
9
+ /**
10
+ * Идентификатор для систем автоматизированного тестирования.
11
+ * Для таба используется модификатор -tab
12
+ */
13
+ dataTestId?: string;
14
+ /**
15
+ * Дополнительные классы для таба.
16
+ */
17
+ tabClassNames?: {
18
+ /**
19
+ * Дополнительный класс таба
20
+ */
21
+ className?: string;
22
+ /**
23
+ * Дополнительный класс таба в выбранном состоянии
24
+ */
25
+ selectedClassName?: string;
26
+ /**
27
+ * Дополнительный класс подписи
28
+ */
29
+ labelClassName?: string;
30
+ /**
31
+ * Дополнительный класс враппера иконки
32
+ */
33
+ iconClassName?: string;
34
+ };
35
+ /**
36
+ * Список табов
37
+ */
38
+ children: TabElementType[];
39
+ /**
40
+ * Идентификатор выбранного таба
41
+ */
42
+ selectedId?: string;
43
+ /**
44
+ * Включает верхний бордер
45
+ */
46
+ border?: boolean;
47
+ /**
48
+ * Обработчик изменения выбранного таба
49
+ */
50
+ onChange?: (id: string) => void;
51
+ }
52
+ type AdditionalTabProps = Record<string, unknown>;
53
+ interface TabProps extends Omit<AllHTMLAttributes<unknown>, 'onChange' | 'label'>, AdditionalTabProps {
54
+ /**
55
+ * Кастомный компонент таба.
56
+ * @default button
57
+ */
58
+ Component?: ElementType;
59
+ /**
60
+ * Идентификатор таба
61
+ */
62
+ id: string;
63
+ /**
64
+ * Лейбл
65
+ */
66
+ label: ReactNode;
67
+ /**
68
+ * Иконка
69
+ */
70
+ icon: ReactNode;
71
+ /**
72
+ * Показать индикатор
73
+ */
74
+ showIndicator?: boolean;
75
+ /**
76
+ * Свойства индикатора
77
+ */
78
+ indicatorProps?: Omit<BadgeProps, 'view' | 'visibleColorOutline' | 'size' | 'iconColor' | 'iconUnderlayColor'>;
79
+ /**
80
+ * Дополнительный класс таба
81
+ */
82
+ className?: string;
83
+ /**
84
+ * Дополнительный класс таба в выбранном состоянии
85
+ */
86
+ selectedClassName?: string;
87
+ /**
88
+ * Дополнительный класс подписи
89
+ */
90
+ labelClassName?: string;
91
+ /**
92
+ * Дополнительный класс враппера иконки
93
+ */
94
+ iconClassName?: string;
95
+ }
96
+ interface PrivateTabProps extends Pick<TabBarProps, 'tabClassNames' | 'onChange' | 'dataTestId'> {
97
+ selected: boolean;
98
+ }
99
+ export { TabBarProps, TabProps, PrivateTabProps };
package/esm/types.js ADDED
@@ -0,0 +1 @@
1
+
package/index.css ADDED
@@ -0,0 +1,30 @@
1
+ /* hash: 1ycka */
2
+ :root {
3
+ } /* deprecated */ :root {
4
+ --color-light-base-bg-primary: #fff;
5
+ --color-light-neutral-300: #e7e8eb; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
6
+ } :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
7
+ } :root {
8
+ } :root {
9
+
10
+ /* Hard */
11
+
12
+ /* Up */
13
+
14
+ /* Hard up */
15
+ } :root {
16
+ } :root {
17
+ } :root {
18
+ } :root {
19
+ } .tab-bar__component_1tqhl {
20
+ display: flex;
21
+ justify-content: center;
22
+ height: 64px;
23
+ max-height: 64px;
24
+ background-color: var(--color-light-base-bg-primary);
25
+ box-sizing: border-box;
26
+ overflow: hidden;
27
+ transition: box-shadow 0.2s ease;
28
+ } .tab-bar__border_1tqhl {
29
+ box-shadow: 0 -1px 0 0 var(--color-light-neutral-300);
30
+ }
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { TabBar } from "./Component";
2
+ export { TabBarProps, TabProps } from "./types";
package/index.js ADDED
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var Component = require('./Component.js');
6
+ require('tslib');
7
+ require('react');
8
+ require('classnames');
9
+ require('@alfalab/core-components-shared');
10
+ require('./components/tab/Component.js');
11
+ require('@alfalab/core-components-badge');
12
+ require('@alfalab/core-components-typography');
13
+
14
+
15
+
16
+ exports.TabBar = Component.TabBar;
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import React from 'react';
3
+ import { TabBarProps } from "./types";
4
+ declare const TabBar: React.ForwardRefExoticComponent<TabBarProps & React.RefAttributes<HTMLDivElement>> & {
5
+ Tab: React.ForwardRefExoticComponent<import("./types").TabProps & React.RefAttributes<HTMLElement>>;
6
+ };
7
+ export { TabBar };
@@ -0,0 +1,25 @@
1
+ import React, { forwardRef, Children, cloneElement } from 'react';
2
+ import cn from 'classnames';
3
+ import { getDataTestId } from '@alfalab/core-components-shared/modern';
4
+ import { Tab } from './components/tab/Component.js';
5
+ import '@alfalab/core-components-badge/modern';
6
+ import '@alfalab/core-components-typography/modern';
7
+
8
+ const styles = {"component":"tab-bar__component_1tqhl","border":"tab-bar__border_1tqhl"};
9
+ require('./index.css')
10
+
11
+ const TabBarComponent = forwardRef(({ children, className, selectedId, border, dataTestId, tabClassNames, onChange, ...restProps }, ref) => {
12
+ if (Children.count(children) > 5) {
13
+ // eslint-disable-next-line no-console
14
+ console.error('Компонент TabBar не может содержать больше 5 табов');
15
+ }
16
+ return (React.createElement("nav", { "data-test-id": dataTestId, ...restProps, ref: ref, className: cn(styles.component, className, { [styles.border]: border }) }, Children.map(children, (tab) => cloneElement(tab, {
17
+ selected: tab.props.id === selectedId,
18
+ onChange,
19
+ tabClassNames,
20
+ dataTestId: getDataTestId(dataTestId, 'tab'),
21
+ }))));
22
+ });
23
+ const TabBar = Object.assign(TabBarComponent, { Tab });
24
+
25
+ export { TabBar };
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import React from 'react';
3
+ import { TabProps } from "../../types";
4
+ declare const Tab: React.ForwardRefExoticComponent<TabProps & React.RefAttributes<HTMLElement>>;
5
+ export { Tab };
@@ -0,0 +1,27 @@
1
+ import React, { forwardRef, isValidElement, cloneElement } from 'react';
2
+ import cn from 'classnames';
3
+ import { Badge } from '@alfalab/core-components-badge/modern';
4
+ import { Typography } from '@alfalab/core-components-typography/modern';
5
+
6
+ const styles = {"component":"tab-bar__component_1cyxn","selected":"tab-bar__selected_1cyxn","icon":"tab-bar__icon_1cyxn","label":"tab-bar__label_1cyxn","labelSelected":"tab-bar__labelSelected_1cyxn","indicator":"tab-bar__indicator_1cyxn"};
7
+ require('./index.css')
8
+
9
+ const TabComponent = forwardRef(({ showIndicator, indicatorProps, label, icon, id, selected, onChange, onClick, tabClassNames = {}, dataTestId, className, labelClassName, selectedClassName, iconClassName, href, Component = href ? 'a' : 'button', ...restProps }, ref) => {
10
+ const handleClick = (event) => {
11
+ onChange?.(id);
12
+ onClick?.(event);
13
+ };
14
+ const { className: commonClassName, labelClassName: commonLabelClassName, selectedClassName: commonSelectedClassName, iconClassName: commonIconClassName, } = tabClassNames;
15
+ return (React.createElement(Component, { "data-test-id": dataTestId, tabIndex: 0, ...(Component === 'button' ? { type: 'button' } : null), ...restProps, href: href, id: id, ref: ref, className: cn(styles.component, commonClassName, className, selected && commonSelectedClassName, selected && selectedClassName, {
16
+ [styles.selected]: selected,
17
+ }), onClick: handleClick },
18
+ React.createElement("div", { className: cn(styles.icon, commonIconClassName, iconClassName) }, isValidElement(icon) ? cloneElement(icon, { selected }) : icon),
19
+ React.createElement(Typography.Text, { weight: 'medium', view: 'secondary-small', className: cn(styles.label, commonLabelClassName, labelClassName, {
20
+ [styles.labelSelected]: selected,
21
+ }) }, isValidElement(label) ? cloneElement(label, { selected }) : label),
22
+ showIndicator && (React.createElement("div", { className: styles.indicator },
23
+ React.createElement(Badge, { visibleIconOutline: true, ...indicatorProps, view: 'count' })))));
24
+ });
25
+ const Tab = TabComponent;
26
+
27
+ export { Tab };
@@ -0,0 +1,71 @@
1
+ /* hash: 8qv7e */
2
+ :root {
3
+ } /* deprecated */ :root {
4
+ --color-light-accent-primary: #ef3124;
5
+ --color-light-neutral-translucent-700: rgba(4, 4, 21, 0.47);
6
+ --color-light-text-secondary: rgba(4, 4, 19, 0.55); /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
7
+ } :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
8
+ } :root {
9
+ } :root {
10
+
11
+ /* Hard */
12
+
13
+ /* Up */
14
+
15
+ /* Hard up */
16
+ } :root {
17
+ } :root {
18
+ --gap-2xs: 4px;
19
+ --gap-xs: 8px;
20
+ } :root {
21
+ } :root {
22
+ } .tab-bar__component_1cyxn {
23
+ box-sizing: border-box;
24
+ background-color: transparent;
25
+ -webkit-tap-highlight-color: transparent;
26
+ outline: none;
27
+ border: 0;
28
+ margin: 0;
29
+ box-shadow: none;
30
+ border-radius: 0;
31
+ -webkit-user-select: none;
32
+ user-select: none;
33
+ vertical-align: middle;
34
+ appearance: none;
35
+ text-decoration: none;
36
+ min-width: 0;
37
+ cursor: pointer;
38
+
39
+ position: relative;
40
+ display: inline-flex;
41
+ flex-direction: column;
42
+ flex: 1 0 0;
43
+ align-items: center;
44
+ padding: var(--gap-xs) 0;
45
+ color: var(--color-light-neutral-translucent-700);
46
+ } .tab-bar__selected_1cyxn {
47
+ color: var(--color-light-accent-primary);
48
+ } .tab-bar__icon_1cyxn {
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ flex-grow: 1;
53
+ width: 100%;
54
+ } .tab-bar__label_1cyxn {
55
+ -webkit-line-clamp: 1;
56
+ display: -webkit-box;
57
+ -webkit-box-orient: vertical;
58
+ overflow: hidden;
59
+ word-break: break-all;
60
+ flex-shrink: 0;
61
+
62
+ color: var(--color-light-text-secondary);
63
+ } .tab-bar__labelSelected_1cyxn {
64
+ color: inherit;
65
+ } .tab-bar__indicator_1cyxn {
66
+ position: absolute;
67
+ top: var(--gap-2xs);
68
+ left: calc(50% + var(--gap-2xs));
69
+ height: 16px;
70
+ min-width: 16px;
71
+ }
@@ -0,0 +1 @@
1
+ export * from "./Component";
@@ -0,0 +1,5 @@
1
+ export { Tab } from './Component.js';
2
+ import 'react';
3
+ import 'classnames';
4
+ import '@alfalab/core-components-badge/modern';
5
+ import '@alfalab/core-components-typography/modern';
@@ -0,0 +1,30 @@
1
+ /* hash: 1ycka */
2
+ :root {
3
+ } /* deprecated */ :root {
4
+ --color-light-base-bg-primary: #fff;
5
+ --color-light-neutral-300: #e7e8eb; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
6
+ } :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
7
+ } :root {
8
+ } :root {
9
+
10
+ /* Hard */
11
+
12
+ /* Up */
13
+
14
+ /* Hard up */
15
+ } :root {
16
+ } :root {
17
+ } :root {
18
+ } :root {
19
+ } .tab-bar__component_1tqhl {
20
+ display: flex;
21
+ justify-content: center;
22
+ height: 64px;
23
+ max-height: 64px;
24
+ background-color: var(--color-light-base-bg-primary);
25
+ box-sizing: border-box;
26
+ overflow: hidden;
27
+ transition: box-shadow 0.2s ease;
28
+ } .tab-bar__border_1tqhl {
29
+ box-shadow: 0 -1px 0 0 var(--color-light-neutral-300);
30
+ }
@@ -0,0 +1,2 @@
1
+ export { TabBar } from "./Component";
2
+ export { TabBarProps, TabProps } from "./types";
@@ -0,0 +1,7 @@
1
+ export { TabBar } from './Component.js';
2
+ import 'react';
3
+ import 'classnames';
4
+ import '@alfalab/core-components-shared/modern';
5
+ import './components/tab/Component.js';
6
+ import '@alfalab/core-components-badge/modern';
7
+ import '@alfalab/core-components-typography/modern';
@@ -0,0 +1,99 @@
1
+ import { AllHTMLAttributes, ElementType, ForwardRefExoticComponent, HTMLAttributes, ReactElement, ReactNode, RefAttributes } from 'react';
2
+ import { BadgeProps } from "@alfalab/core-components-badge";
3
+ type TabElementType = ReactElement<TabProps, ForwardRefExoticComponent<TabProps & RefAttributes<HTMLElement>>>;
4
+ interface TabBarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
5
+ /**
6
+ * Дополнительный класс
7
+ */
8
+ className?: string;
9
+ /**
10
+ * Идентификатор для систем автоматизированного тестирования.
11
+ * Для таба используется модификатор -tab
12
+ */
13
+ dataTestId?: string;
14
+ /**
15
+ * Дополнительные классы для таба.
16
+ */
17
+ tabClassNames?: {
18
+ /**
19
+ * Дополнительный класс таба
20
+ */
21
+ className?: string;
22
+ /**
23
+ * Дополнительный класс таба в выбранном состоянии
24
+ */
25
+ selectedClassName?: string;
26
+ /**
27
+ * Дополнительный класс подписи
28
+ */
29
+ labelClassName?: string;
30
+ /**
31
+ * Дополнительный класс враппера иконки
32
+ */
33
+ iconClassName?: string;
34
+ };
35
+ /**
36
+ * Список табов
37
+ */
38
+ children: TabElementType[];
39
+ /**
40
+ * Идентификатор выбранного таба
41
+ */
42
+ selectedId?: string;
43
+ /**
44
+ * Включает верхний бордер
45
+ */
46
+ border?: boolean;
47
+ /**
48
+ * Обработчик изменения выбранного таба
49
+ */
50
+ onChange?: (id: string) => void;
51
+ }
52
+ type AdditionalTabProps = Record<string, unknown>;
53
+ interface TabProps extends Omit<AllHTMLAttributes<unknown>, 'onChange' | 'label'>, AdditionalTabProps {
54
+ /**
55
+ * Кастомный компонент таба.
56
+ * @default button
57
+ */
58
+ Component?: ElementType;
59
+ /**
60
+ * Идентификатор таба
61
+ */
62
+ id: string;
63
+ /**
64
+ * Лейбл
65
+ */
66
+ label: ReactNode;
67
+ /**
68
+ * Иконка
69
+ */
70
+ icon: ReactNode;
71
+ /**
72
+ * Показать индикатор
73
+ */
74
+ showIndicator?: boolean;
75
+ /**
76
+ * Свойства индикатора
77
+ */
78
+ indicatorProps?: Omit<BadgeProps, 'view' | 'visibleColorOutline' | 'size' | 'iconColor' | 'iconUnderlayColor'>;
79
+ /**
80
+ * Дополнительный класс таба
81
+ */
82
+ className?: string;
83
+ /**
84
+ * Дополнительный класс таба в выбранном состоянии
85
+ */
86
+ selectedClassName?: string;
87
+ /**
88
+ * Дополнительный класс подписи
89
+ */
90
+ labelClassName?: string;
91
+ /**
92
+ * Дополнительный класс враппера иконки
93
+ */
94
+ iconClassName?: string;
95
+ }
96
+ interface PrivateTabProps extends Pick<TabBarProps, 'tabClassNames' | 'onChange' | 'dataTestId'> {
97
+ selected: boolean;
98
+ }
99
+ export { TabBarProps, TabProps, PrivateTabProps };
@@ -0,0 +1 @@
1
+
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@alfalab/core-components-tab-bar",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "keywords": [],
6
+ "license": "MIT",
7
+ "main": "index.js",
8
+ "module": "./esm/index.js",
9
+ "publishConfig": {
10
+ "access": "public",
11
+ "directory": "dist"
12
+ },
13
+ "peerDependencies": {
14
+ "react": ">=16.8.0",
15
+ "react-dom": ">=16.8.0"
16
+ },
17
+ "dependencies": {
18
+ "@alfalab/core-components-typography": "^4.2.1",
19
+ "@alfalab/core-components-badge": "^5.4.0",
20
+ "@alfalab/core-components-shared": "^0.8.0",
21
+ "classnames": "^2.3.1",
22
+ "tslib": "^2.4.0"
23
+ }
24
+ }
@@ -0,0 +1,50 @@
1
+ import React, { Children, cloneElement, forwardRef } from 'react';
2
+ import cn from 'classnames';
3
+
4
+ import { getDataTestId } from '@alfalab/core-components-shared';
5
+
6
+ import { Tab } from './components/tab';
7
+ import { TabBarProps } from './types';
8
+
9
+ import styles from './index.module.css';
10
+
11
+ const TabBarComponent = forwardRef<HTMLDivElement, TabBarProps>(
12
+ (
13
+ {
14
+ children,
15
+ className,
16
+ selectedId,
17
+ border,
18
+ dataTestId,
19
+ tabClassNames,
20
+ onChange,
21
+ ...restProps
22
+ },
23
+ ref,
24
+ ) => {
25
+ if (Children.count(children) > 5) {
26
+ // eslint-disable-next-line no-console
27
+ console.error('Компонент TabBar не может содержать больше 5 табов');
28
+ }
29
+
30
+ return (
31
+ <nav
32
+ data-test-id={dataTestId}
33
+ {...restProps}
34
+ ref={ref}
35
+ className={cn(styles.component, className, { [styles.border]: border })}
36
+ >
37
+ {Children.map(children, (tab) =>
38
+ cloneElement(tab, {
39
+ selected: tab.props.id === selectedId,
40
+ onChange,
41
+ tabClassNames,
42
+ dataTestId: getDataTestId(dataTestId, 'tab'),
43
+ }),
44
+ )}
45
+ </nav>
46
+ );
47
+ },
48
+ );
49
+
50
+ export const TabBar = Object.assign(TabBarComponent, { Tab });