@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,93 @@
1
+ import React, { cloneElement, forwardRef, isValidElement, MouseEvent } from 'react';
2
+ import cn from 'classnames';
3
+
4
+ import { Badge } from '@alfalab/core-components-badge';
5
+ import { Typography } from '@alfalab/core-components-typography';
6
+
7
+ import { PrivateTabProps, TabProps } from '../../types';
8
+
9
+ import styles from './index.module.css';
10
+
11
+ const TabComponent = forwardRef(
12
+ (
13
+ {
14
+ showIndicator,
15
+ indicatorProps,
16
+ label,
17
+ icon,
18
+ id,
19
+ selected,
20
+ onChange,
21
+ onClick,
22
+ tabClassNames = {},
23
+ dataTestId,
24
+ className,
25
+ labelClassName,
26
+ selectedClassName,
27
+ iconClassName,
28
+ href,
29
+ Component = href ? 'a' : 'button',
30
+ ...restProps
31
+ }: PrivateTabProps & TabProps,
32
+ ref,
33
+ ) => {
34
+ const handleClick = (event: MouseEvent) => {
35
+ onChange?.(id);
36
+ onClick?.(event);
37
+ };
38
+
39
+ const {
40
+ className: commonClassName,
41
+ labelClassName: commonLabelClassName,
42
+ selectedClassName: commonSelectedClassName,
43
+ iconClassName: commonIconClassName,
44
+ } = tabClassNames;
45
+
46
+ return (
47
+ <Component
48
+ data-test-id={dataTestId}
49
+ tabIndex={0}
50
+ {...(Component === 'button' ? { type: 'button' } : null)}
51
+ {...restProps}
52
+ href={href}
53
+ id={id}
54
+ ref={ref}
55
+ className={cn(
56
+ styles.component,
57
+ commonClassName,
58
+ className,
59
+ selected && commonSelectedClassName,
60
+ selected && selectedClassName,
61
+ {
62
+ [styles.selected]: selected,
63
+ },
64
+ )}
65
+ onClick={handleClick}
66
+ >
67
+ <div className={cn(styles.icon, commonIconClassName, iconClassName)}>
68
+ {isValidElement(icon) ? cloneElement(icon, { selected }) : icon}
69
+ </div>
70
+
71
+ <Typography.Text
72
+ weight='medium'
73
+ view='secondary-small'
74
+ className={cn(styles.label, commonLabelClassName, labelClassName, {
75
+ [styles.labelSelected]: selected,
76
+ })}
77
+ >
78
+ {isValidElement(label) ? cloneElement(label, { selected }) : label}
79
+ </Typography.Text>
80
+
81
+ {showIndicator && (
82
+ <div className={styles.indicator}>
83
+ <Badge visibleIconOutline={true} {...indicatorProps} view='count' />
84
+ </div>
85
+ )}
86
+ </Component>
87
+ );
88
+ },
89
+ );
90
+
91
+ export const Tab = TabComponent as React.ForwardRefExoticComponent<
92
+ TabProps & React.RefAttributes<HTMLElement>
93
+ >;
@@ -0,0 +1,45 @@
1
+ @import '@alfalab/core-components-themes/src/default.css';
2
+
3
+ .component {
4
+ @mixin button-reset;
5
+
6
+ position: relative;
7
+ display: inline-flex;
8
+ flex-direction: column;
9
+ flex: 1 0 0;
10
+ align-items: center;
11
+ padding: var(--gap-xs) 0;
12
+ color: var(--color-light-neutral-translucent-700);
13
+ }
14
+
15
+ .selected {
16
+ color: var(--color-light-accent-primary);
17
+ }
18
+
19
+ .icon {
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+ flex-grow: 1;
24
+ width: 100%;
25
+ }
26
+
27
+ .label {
28
+ @mixin row_limit 1;
29
+ word-break: break-all;
30
+ flex-shrink: 0;
31
+
32
+ color: var(--color-light-text-secondary);
33
+ }
34
+
35
+ .labelSelected {
36
+ color: inherit;
37
+ }
38
+
39
+ .indicator {
40
+ position: absolute;
41
+ top: var(--gap-2xs);
42
+ left: calc(50% + var(--gap-2xs));
43
+ height: 16px;
44
+ min-width: 16px;
45
+ }
@@ -0,0 +1 @@
1
+ export * from './Component';
@@ -0,0 +1,16 @@
1
+ @import '@alfalab/core-components-themes/src/default.css';
2
+
3
+ .component {
4
+ display: flex;
5
+ justify-content: center;
6
+ height: 64px;
7
+ max-height: 64px;
8
+ background-color: var(--color-light-base-bg-primary);
9
+ box-sizing: border-box;
10
+ overflow: hidden;
11
+ transition: box-shadow 0.2s ease;
12
+ }
13
+
14
+ .border {
15
+ box-shadow: 0 -1px 0 0 var(--color-light-neutral-300);
16
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { TabBar } from './Component';
2
+ export { TabBarProps, TabProps } from './types';
package/src/types.ts ADDED
@@ -0,0 +1,139 @@
1
+ import type {
2
+ AllHTMLAttributes,
3
+ ElementType,
4
+ ForwardRefExoticComponent,
5
+ HTMLAttributes,
6
+ ReactElement,
7
+ ReactNode,
8
+ RefAttributes,
9
+ } from 'react';
10
+
11
+ import type { BadgeProps } from '@alfalab/core-components-badge';
12
+
13
+ type TabElementType = ReactElement<
14
+ TabProps,
15
+ ForwardRefExoticComponent<TabProps & RefAttributes<HTMLElement>>
16
+ >;
17
+
18
+ export interface TabBarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
19
+ /**
20
+ * Дополнительный класс
21
+ */
22
+ className?: string;
23
+
24
+ /**
25
+ * Идентификатор для систем автоматизированного тестирования.
26
+ * Для таба используется модификатор -tab
27
+ */
28
+ dataTestId?: string;
29
+
30
+ /**
31
+ * Дополнительные классы для таба.
32
+ */
33
+ tabClassNames?: {
34
+ /**
35
+ * Дополнительный класс таба
36
+ */
37
+ className?: string;
38
+
39
+ /**
40
+ * Дополнительный класс таба в выбранном состоянии
41
+ */
42
+ selectedClassName?: string;
43
+
44
+ /**
45
+ * Дополнительный класс подписи
46
+ */
47
+ labelClassName?: string;
48
+
49
+ /**
50
+ * Дополнительный класс враппера иконки
51
+ */
52
+ iconClassName?: string;
53
+ };
54
+
55
+ /**
56
+ * Список табов
57
+ */
58
+ children: TabElementType[];
59
+
60
+ /**
61
+ * Идентификатор выбранного таба
62
+ */
63
+ selectedId?: string;
64
+
65
+ /**
66
+ * Включает верхний бордер
67
+ */
68
+ border?: boolean;
69
+
70
+ /**
71
+ * Обработчик изменения выбранного таба
72
+ */
73
+ onChange?: (id: string) => void;
74
+ }
75
+
76
+ type AdditionalTabProps = Record<string, unknown>;
77
+
78
+ export interface TabProps
79
+ extends Omit<AllHTMLAttributes<unknown>, 'onChange' | 'label'>,
80
+ AdditionalTabProps {
81
+ /**
82
+ * Кастомный компонент таба.
83
+ * @default button
84
+ */
85
+ Component?: ElementType;
86
+
87
+ /**
88
+ * Идентификатор таба
89
+ */
90
+ id: string;
91
+
92
+ /**
93
+ * Лейбл
94
+ */
95
+ label: ReactNode;
96
+
97
+ /**
98
+ * Иконка
99
+ */
100
+ icon: ReactNode;
101
+
102
+ /**
103
+ * Показать индикатор
104
+ */
105
+ showIndicator?: boolean;
106
+
107
+ /**
108
+ * Свойства индикатора
109
+ */
110
+ indicatorProps?: Omit<
111
+ BadgeProps,
112
+ 'view' | 'visibleColorOutline' | 'size' | 'iconColor' | 'iconUnderlayColor'
113
+ >;
114
+
115
+ /**
116
+ * Дополнительный класс таба
117
+ */
118
+ className?: string;
119
+
120
+ /**
121
+ * Дополнительный класс таба в выбранном состоянии
122
+ */
123
+ selectedClassName?: string;
124
+
125
+ /**
126
+ * Дополнительный класс подписи
127
+ */
128
+ labelClassName?: string;
129
+
130
+ /**
131
+ * Дополнительный класс враппера иконки
132
+ */
133
+ iconClassName?: string;
134
+ }
135
+
136
+ export interface PrivateTabProps
137
+ extends Pick<TabBarProps, 'tabClassNames' | 'onChange' | 'dataTestId'> {
138
+ selected: boolean;
139
+ }
package/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/types.js ADDED
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+