@snack-uikit/card 0.9.12-preview-993a9cfb.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +2 -1
- package/dist/components/Card/Card.d.ts +5 -3
- package/dist/components/Card/Card.js +11 -8
- package/dist/components/Card/styles.module.css +11 -0
- package/dist/components/Footer/components/CallToAction/styles.module.css +4 -4
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/package.json +7 -7
- package/src/components/Card/Card.tsx +26 -9
- package/src/components/Card/styles.module.scss +13 -0
- package/src/components/Footer/components/CallToAction/styles.module.scss +4 -4
- package/src/constants.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 0.10.0 (2024-02-20)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **FF-4295:** add href prop ([8874f1c](https://github.com/cloud-ru-tech/snack-uikit/commit/8874f1c5fef99ce1ef3033977de9fd538e829f42))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## 0.9.11 (2024-02-13)
|
|
7
18
|
|
|
8
19
|
### Only dependencies have been changed
|
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ import { Card, SearchPrivate } from "@snack-uikit/card";
|
|
|
32
32
|
| checked | `boolean` | - | Управление состоянием выбран/не выбран |
|
|
33
33
|
| outline | `boolean` | - | Управление состоянием наличия обводки |
|
|
34
34
|
| multipleSelection | `boolean` | - | Отображение галочки для режима массового выделения карточек |
|
|
35
|
-
| onClick | `() => void` | - | Колбек на клик по карточке |
|
|
35
|
+
| onClick | `(e: MouseEvent<HTMLDivElement \| HTMLAnchorElement, MouseEvent>) => void` | - | Колбек на клик по карточке |
|
|
36
36
|
| size | enum Size: `"s"`, `"m"`, `"l"` | - | Размер |
|
|
37
37
|
| promoBadge | `string` | - | Текст для PromoBadge |
|
|
38
38
|
| children | `ReactNode` | - | Вложенный контент |
|
|
@@ -41,6 +41,7 @@ import { Card, SearchPrivate } from "@snack-uikit/card";
|
|
|
41
41
|
| image | `ReactNode` | - | Вложенный Image |
|
|
42
42
|
| functionBadge | `ReactNode` | - | Вложенный FunctionBadge |
|
|
43
43
|
| className | `string` | - | CSS-класс для элемента с контентом |
|
|
44
|
+
| href | `string` | - | Ссылка карточки |
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
[//]: DOCUMENTATION_SECTION_END
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactElement, ReactNode } from 'react';
|
|
1
|
+
import { MouseEvent, ReactElement, ReactNode } from 'react';
|
|
2
2
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
3
3
|
import { Size } from '../../types';
|
|
4
4
|
import { HeaderProps } from '../Header';
|
|
@@ -12,7 +12,7 @@ export type CardProps = WithSupportProps<{
|
|
|
12
12
|
/** Отображение галочки для режима массового выделения карточек */
|
|
13
13
|
multipleSelection?: boolean;
|
|
14
14
|
/** Колбек на клик по карточке */
|
|
15
|
-
onClick?(): void;
|
|
15
|
+
onClick?(e: MouseEvent<HTMLDivElement | HTMLAnchorElement>): void;
|
|
16
16
|
/** Размер */
|
|
17
17
|
size?: Size;
|
|
18
18
|
/** Текст для PromoBadge */
|
|
@@ -29,5 +29,7 @@ export type CardProps = WithSupportProps<{
|
|
|
29
29
|
functionBadge?: ReactNode;
|
|
30
30
|
/** CSS-класс для элемента с контентом */
|
|
31
31
|
className?: string;
|
|
32
|
+
/** Ссылка карточки */
|
|
33
|
+
href?: string;
|
|
32
34
|
}>;
|
|
33
|
-
export declare function Card({ onClick, disabled, checked, outline, multipleSelection, size, children, header, footer, functionBadge, promoBadge, image, className, ...rest }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
export declare function Card({ onClick, disabled, checked, outline, multipleSelection, size, children, header, footer, functionBadge, promoBadge, image, className, href, ...rest }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,22 +14,25 @@ import cn from 'classnames';
|
|
|
14
14
|
import { useCallback, useRef } from 'react';
|
|
15
15
|
import { Typography } from '@snack-uikit/typography';
|
|
16
16
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
17
|
-
import { SIZE } from '../../constants';
|
|
17
|
+
import { SIZE, TEST_IDS } from '../../constants';
|
|
18
18
|
import { CardContext } from '../../context';
|
|
19
19
|
import { Check, FunctionBadgeWrapper, PromoBadge } from '../../helperComponents';
|
|
20
20
|
import { TRIGGER_CLICK_KEY_CODES } from './constants';
|
|
21
21
|
import styles from './styles.module.css';
|
|
22
22
|
export function Card(_a) {
|
|
23
|
-
var { onClick, disabled = false, checked, outline, multipleSelection = false, size = SIZE.M, children, header, footer, functionBadge, promoBadge, image, className } = _a, rest = __rest(_a, ["onClick", "disabled", "checked", "outline", "multipleSelection", "size", "children", "header", "footer", "functionBadge", "promoBadge", "image", "className"]);
|
|
24
|
-
const
|
|
23
|
+
var { onClick, disabled = false, checked, outline, multipleSelection = false, size = SIZE.M, children, header, footer, functionBadge, promoBadge, image, className, href } = _a, rest = __rest(_a, ["onClick", "disabled", "checked", "outline", "multipleSelection", "size", "children", "header", "footer", "functionBadge", "promoBadge", "image", "className", "href"]);
|
|
24
|
+
const localDivRef = useRef(null);
|
|
25
|
+
const localAnchorRef = useRef(null);
|
|
25
26
|
const onKeyDown = useCallback((e) => {
|
|
26
|
-
|
|
27
|
+
var _a, _b;
|
|
28
|
+
if (e.target === localDivRef.current) {
|
|
27
29
|
if (TRIGGER_CLICK_KEY_CODES.includes(e.code)) {
|
|
28
|
-
|
|
30
|
+
href ? (_a = localAnchorRef.current) === null || _a === void 0 ? void 0 : _a.click() : (_b = localDivRef.current) === null || _b === void 0 ? void 0 : _b.click();
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
|
-
}, [
|
|
32
|
-
|
|
33
|
+
}, [href]);
|
|
34
|
+
const supportProps = extractSupportProps(rest);
|
|
35
|
+
return (_jsx(CardContext.Provider, { value: { size, disabled }, children: _jsxs("div", Object.assign({ ref: localDivRef, className: cn(styles.card, className) }, supportProps, { onClick: onClick, "data-disabled": disabled || undefined, "data-checked": checked || undefined, "data-outline": outline || undefined, "data-pointer": onClick ? true : undefined,
|
|
33
36
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
34
|
-
tabIndex: 0, onKeyDown: onKeyDown, children: [image, promoBadge && _jsx(PromoBadge, { text: promoBadge }), _jsxs("div", { className: styles.composition, tabIndex: -1, children: [!disabled && functionBadge && (_jsx(FunctionBadgeWrapper, { className: styles.functionBadgeWrapper, children: functionBadge })), _jsx("div", { className: styles.contentWrapper, children: _jsxs("div", { className: styles.content, "data-size": size, children: [header || null, children && (_jsx(Typography, { family: 'sans', size: size, purpose: 'body', className: styles.body, tag: 'div', children: children })), footer && _jsx("div", { className: styles.footer, children: footer })] }) })] }), !disabled && checked && multipleSelection && _jsx(Check, { className: styles.check })] })) }));
|
|
37
|
+
tabIndex: 0, onKeyDown: onKeyDown, children: [image, promoBadge && _jsx(PromoBadge, { text: promoBadge }), _jsxs("div", { className: styles.composition, tabIndex: -1, children: [href && (_jsx("a", { ref: localAnchorRef, "data-test-id": TEST_IDS.anchor, tabIndex: -1, href: href, className: styles.anchor, "aria-label": supportProps['aria-label'] })), !disabled && functionBadge && (_jsx(FunctionBadgeWrapper, { className: styles.functionBadgeWrapper, children: functionBadge })), _jsx("div", { className: styles.contentWrapper, children: _jsxs("div", { className: styles.content, "data-size": size, children: [header || null, children && (_jsx(Typography, { family: 'sans', size: size, purpose: 'body', className: styles.body, tag: 'div', children: children })), footer && _jsx("div", { className: styles.footer, children: footer })] }) })] }), !disabled && checked && multipleSelection && _jsx(Check, { className: styles.check })] })) }));
|
|
35
38
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
.functionBadgeWrapper{
|
|
2
2
|
position:absolute;
|
|
3
|
+
z-index:1;
|
|
3
4
|
top:0;
|
|
4
5
|
right:0;
|
|
5
6
|
display:none;
|
|
@@ -125,6 +126,16 @@
|
|
|
125
126
|
cursor:not-allowed;
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
.anchor{
|
|
130
|
+
position:absolute;
|
|
131
|
+
z-index:1;
|
|
132
|
+
top:0;
|
|
133
|
+
right:0;
|
|
134
|
+
bottom:0;
|
|
135
|
+
left:0;
|
|
136
|
+
border-radius:var(--radius-card-container, 20px);
|
|
137
|
+
}
|
|
138
|
+
|
|
128
139
|
.body{
|
|
129
140
|
display:block;
|
|
130
141
|
width:100%;
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
box-sizing:border-box;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
.label{
|
|
10
|
+
color:var(--sys-primary-accent-default, #794ed3);
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
.icon{
|
|
10
14
|
display:flex;
|
|
11
15
|
align-items:center;
|
|
@@ -15,8 +19,4 @@
|
|
|
15
19
|
.icon svg{
|
|
16
20
|
width:var(--size-icon-container-s, 24px) !important;
|
|
17
21
|
height:var(--size-icon-container-s, 24px) !important;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.label{
|
|
21
|
-
color:var(--sys-primary-accent-default, #794ed3);
|
|
22
22
|
}
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Card",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.10.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -32,16 +32,16 @@
|
|
|
32
32
|
"license": "Apache-2.0",
|
|
33
33
|
"scripts": {},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@snack-uikit/button": "0.16.
|
|
36
|
-
"@snack-uikit/icon-predefined": "0.4.
|
|
35
|
+
"@snack-uikit/button": "0.16.0",
|
|
36
|
+
"@snack-uikit/icon-predefined": "0.4.1",
|
|
37
37
|
"@snack-uikit/icons": "0.20.1",
|
|
38
|
-
"@snack-uikit/list": "0.3.
|
|
38
|
+
"@snack-uikit/list": "0.3.3",
|
|
39
39
|
"@snack-uikit/promo-tag": "0.4.1",
|
|
40
|
-
"@snack-uikit/tag": "0.7.
|
|
41
|
-
"@snack-uikit/truncate-string": "0.4.
|
|
40
|
+
"@snack-uikit/tag": "0.7.3",
|
|
41
|
+
"@snack-uikit/truncate-string": "0.4.7",
|
|
42
42
|
"@snack-uikit/typography": "0.6.1",
|
|
43
43
|
"@snack-uikit/utils": "3.2.0",
|
|
44
44
|
"classnames": "2.3.2"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "c812034af313f7a0f6247e848e83e783e181032c"
|
|
47
47
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import cn from 'classnames';
|
|
2
|
-
import { KeyboardEvent, ReactElement, ReactNode, useCallback, useRef } from 'react';
|
|
2
|
+
import { KeyboardEvent, MouseEvent, ReactElement, ReactNode, useCallback, useRef } from 'react';
|
|
3
3
|
|
|
4
4
|
import { Typography } from '@snack-uikit/typography';
|
|
5
5
|
import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
|
|
6
6
|
|
|
7
|
-
import { SIZE } from '../../constants';
|
|
7
|
+
import { SIZE, TEST_IDS } from '../../constants';
|
|
8
8
|
import { CardContext } from '../../context';
|
|
9
9
|
import { Check, FunctionBadgeWrapper, PromoBadge } from '../../helperComponents';
|
|
10
10
|
import { Size } from '../../types';
|
|
@@ -22,7 +22,7 @@ export type CardProps = WithSupportProps<{
|
|
|
22
22
|
/** Отображение галочки для режима массового выделения карточек */
|
|
23
23
|
multipleSelection?: boolean;
|
|
24
24
|
/** Колбек на клик по карточке */
|
|
25
|
-
onClick?(): void;
|
|
25
|
+
onClick?(e: MouseEvent<HTMLDivElement | HTMLAnchorElement>): void;
|
|
26
26
|
/** Размер */
|
|
27
27
|
size?: Size;
|
|
28
28
|
/** Текст для PromoBadge */
|
|
@@ -39,6 +39,8 @@ export type CardProps = WithSupportProps<{
|
|
|
39
39
|
functionBadge?: ReactNode;
|
|
40
40
|
/** CSS-класс для элемента с контентом */
|
|
41
41
|
className?: string;
|
|
42
|
+
/** Ссылка карточки */
|
|
43
|
+
href?: string;
|
|
42
44
|
}>;
|
|
43
45
|
|
|
44
46
|
export function Card({
|
|
@@ -55,28 +57,32 @@ export function Card({
|
|
|
55
57
|
promoBadge,
|
|
56
58
|
image,
|
|
57
59
|
className,
|
|
60
|
+
href,
|
|
58
61
|
...rest
|
|
59
62
|
}: CardProps) {
|
|
60
|
-
const
|
|
63
|
+
const localDivRef = useRef<HTMLDivElement>(null);
|
|
64
|
+
const localAnchorRef = useRef<HTMLAnchorElement>(null);
|
|
61
65
|
|
|
62
66
|
const onKeyDown = useCallback(
|
|
63
67
|
(e: KeyboardEvent<HTMLDivElement>) => {
|
|
64
|
-
if (e.target ===
|
|
68
|
+
if (e.target === localDivRef.current) {
|
|
65
69
|
if (TRIGGER_CLICK_KEY_CODES.includes(e.code)) {
|
|
66
|
-
|
|
70
|
+
href ? localAnchorRef.current?.click() : localDivRef.current?.click();
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
},
|
|
70
|
-
[
|
|
74
|
+
[href],
|
|
71
75
|
);
|
|
72
76
|
|
|
77
|
+
const supportProps = extractSupportProps(rest);
|
|
78
|
+
|
|
73
79
|
return (
|
|
74
80
|
<CardContext.Provider value={{ size, disabled }}>
|
|
75
81
|
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
|
|
76
82
|
<div
|
|
77
|
-
ref={
|
|
83
|
+
ref={localDivRef}
|
|
78
84
|
className={cn(styles.card, className)}
|
|
79
|
-
{...
|
|
85
|
+
{...supportProps}
|
|
80
86
|
onClick={onClick}
|
|
81
87
|
data-disabled={disabled || undefined}
|
|
82
88
|
data-checked={checked || undefined}
|
|
@@ -91,6 +97,17 @@ export function Card({
|
|
|
91
97
|
{promoBadge && <PromoBadge text={promoBadge} />}
|
|
92
98
|
|
|
93
99
|
<div className={styles.composition} tabIndex={-1}>
|
|
100
|
+
{href && (
|
|
101
|
+
<a
|
|
102
|
+
ref={localAnchorRef}
|
|
103
|
+
data-test-id={TEST_IDS.anchor}
|
|
104
|
+
tabIndex={-1}
|
|
105
|
+
href={href}
|
|
106
|
+
className={styles.anchor}
|
|
107
|
+
aria-label={supportProps['aria-label'] as string}
|
|
108
|
+
/>
|
|
109
|
+
)}
|
|
110
|
+
|
|
94
111
|
{!disabled && functionBadge && (
|
|
95
112
|
<FunctionBadgeWrapper className={styles.functionBadgeWrapper}>{functionBadge}</FunctionBadgeWrapper>
|
|
96
113
|
)}
|
|
@@ -5,8 +5,10 @@ $sizes: 's', 'm', 'l';
|
|
|
5
5
|
|
|
6
6
|
.functionBadgeWrapper {
|
|
7
7
|
position: absolute;
|
|
8
|
+
z-index: 1;
|
|
8
9
|
top: 0;
|
|
9
10
|
right: 0;
|
|
11
|
+
|
|
10
12
|
display: none;
|
|
11
13
|
|
|
12
14
|
&[data-visible] {
|
|
@@ -160,6 +162,17 @@ $sizes: 's', 'm', 'l';
|
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
164
|
|
|
165
|
+
.anchor {
|
|
166
|
+
position: absolute;
|
|
167
|
+
z-index: 1;
|
|
168
|
+
top: 0;
|
|
169
|
+
right: 0;
|
|
170
|
+
bottom: 0;
|
|
171
|
+
left: 0;
|
|
172
|
+
|
|
173
|
+
border-radius: $radius-card-container;
|
|
174
|
+
}
|
|
175
|
+
|
|
163
176
|
.body {
|
|
164
177
|
display: block;
|
|
165
178
|
width: 100%;
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
box-sizing: border-box;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
.label {
|
|
14
|
+
color: $sys-primary-accent-default;
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
.icon {
|
|
14
18
|
display: flex;
|
|
15
19
|
align-items: center;
|
|
@@ -20,8 +24,4 @@
|
|
|
20
24
|
width: $icon-s !important; /* stylelint-disable-line declaration-no-important */
|
|
21
25
|
height: $icon-s !important; /* stylelint-disable-line declaration-no-important */
|
|
22
26
|
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.label {
|
|
26
|
-
color: $sys-primary-accent-default;
|
|
27
27
|
}
|