@snack-uikit/link 0.15.13 → 0.16.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 +11 -8
- package/dist/cjs/components/Link.d.ts +3 -39
- package/dist/cjs/components/Link.js +23 -14
- package/dist/cjs/components/index.d.ts +1 -0
- package/dist/cjs/components/types.d.ts +48 -1
- package/dist/esm/components/Link.d.ts +3 -39
- package/dist/esm/components/Link.js +16 -3
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/types.d.ts +48 -1
- package/package.json +2 -2
- package/src/components/Link.tsx +28 -54
- package/src/components/index.ts +1 -0
- package/src/components/types.ts +56 -1
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.16.0 (2025-03-06)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **SAEVO-161:** Allow custom link component integration. ([40ff813](https://github.com/cloud-ru-tech/snack-uikit/commit/40ff813a7d652e309df6d506c51b56a811c8edaa))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## 0.15.13 (2025-03-05)
|
|
7
18
|
|
|
8
19
|
### Only dependencies have been changed
|
package/README.md
CHANGED
|
@@ -12,14 +12,21 @@
|
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
14
|
import { Link } from '@snack-uikit/link';
|
|
15
|
+
import { Link as ReactRouterLink } from 'react-router-dom';
|
|
15
16
|
|
|
16
17
|
<Link
|
|
17
|
-
onSurface='accent'
|
|
18
18
|
href='https://cloud.ru/'
|
|
19
19
|
text='Link text'
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
size='m'
|
|
21
|
+
appearance='neutral'
|
|
22
|
+
onClick={e => {
|
|
23
|
+
e.stopPropagation();
|
|
24
|
+
}}
|
|
22
25
|
/>;
|
|
26
|
+
|
|
27
|
+
// Polymorphic components
|
|
28
|
+
|
|
29
|
+
<Link as={ReactRouterLink} text='Link text' size='m' appearance='neutral' to='..' />;
|
|
23
30
|
```
|
|
24
31
|
|
|
25
32
|
[//]: DOCUMENTATION_SECTION_START
|
|
@@ -30,16 +37,12 @@ import { Link } from '@snack-uikit/link';
|
|
|
30
37
|
| name | type | default value | description |
|
|
31
38
|
|------|------|---------------|-------------|
|
|
32
39
|
| text | `string` | - | Текст ссылки |
|
|
33
|
-
| className | `string` | - | CSS-класс |
|
|
34
|
-
| href | `string` | # | Ссылка |
|
|
35
|
-
| target | `HTMLAttributeAnchorTarget` | _blank | HTML-атрибут target |
|
|
36
|
-
| download | `string` | - | HTML-атрибут download |
|
|
37
|
-
| onClick | `MouseEventHandler<HTMLAnchorElement>` | - | Колбек обработки клика |
|
|
38
40
|
| size | enum Size: `"s"`, `"m"`, `"l"` | s | Размер |
|
|
39
41
|
| appearance | enum Appearance: `"invert-neutral"`, `"neutral"`, `"primary"`, `"red"`, `"orange"`, `"yellow"`, `"green"`, `"blue"`, `"violet"`, `"pink"` | primary | Стилизует ссылку для размещения на цветном фоне |
|
|
40
42
|
| textMode | enum TextMode: `"default"`, `"accent"`, `"on-accent"` | default | Тип поверхности, на которой размещена ссылка |
|
|
41
43
|
| insideText | `boolean` | - | Находится ли ссылка внутри текста (и можно ли её переносить) |
|
|
42
44
|
| truncateVariant | "end" \| "middle" | - | Вариант обрезания строки: <br> - `end` - с конца; <br> - `middle` - по середине |
|
|
45
|
+
| as | `ComponentType \| ElementType` | 'a' | Полиморфный компонент. Оформить переданный компонент или html элемент в стиль ссылки. Список атрибутов, которые переданный компонент должен принять: <br/> - `className` <br/> - `data-size` <br/> - `data-text-mode` <br/> - `data-appearance` <br/> - `data-inside-text` |
|
|
43
46
|
|
|
44
47
|
|
|
45
48
|
[//]: DOCUMENTATION_SECTION_END
|
|
@@ -1,40 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { WithSupportProps } from '@snack-uikit/utils';
|
|
4
|
-
import { Appearance, Size, TextMode } from './types';
|
|
5
|
-
export type LinkProps = WithSupportProps<{
|
|
6
|
-
/** Текст ссылки */
|
|
7
|
-
text?: string;
|
|
8
|
-
/** CSS-класс */
|
|
9
|
-
className?: string;
|
|
10
|
-
/** Ссылка */
|
|
11
|
-
href?: string;
|
|
12
|
-
/** HTML-атрибут target */
|
|
13
|
-
target?: AnchorHTMLAttributes<HTMLAnchorElement>['target'];
|
|
14
|
-
/** HTML-атрибут download */
|
|
15
|
-
download?: string;
|
|
16
|
-
/** Колбек обработки клика */
|
|
17
|
-
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
18
|
-
/** Размер
|
|
19
|
-
* @default 's'
|
|
20
|
-
*/
|
|
21
|
-
size?: Size;
|
|
22
|
-
/** Стилизует ссылку для размещения на цветном фоне
|
|
23
|
-
* @default 'primary'
|
|
24
|
-
*/
|
|
25
|
-
appearance?: Appearance;
|
|
26
|
-
/** Тип поверхности, на которой размещена ссылка
|
|
27
|
-
* @default 'default'
|
|
28
|
-
*/
|
|
29
|
-
textMode?: TextMode;
|
|
30
|
-
/** Находится ли ссылка внутри текста (и можно ли её переносить) */
|
|
31
|
-
insideText?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Вариант обрезания строки:
|
|
34
|
-
* <br> - `end` - с конца;
|
|
35
|
-
* <br> - `middle` - по середине
|
|
36
|
-
* */
|
|
37
|
-
truncateVariant?: TruncateStringProps['variant'];
|
|
38
|
-
}>;
|
|
1
|
+
import { ElementType } from 'react';
|
|
2
|
+
import { LinkProps } from './types';
|
|
39
3
|
/** Компонент ссылка */
|
|
40
|
-
export declare function Link({ text, className,
|
|
4
|
+
export declare function Link<T extends ElementType = 'a'>({ text, className, textMode, size, appearance, insideText, truncateVariant, as, ...rest }: LinkProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -25,32 +25,41 @@ const constants_1 = require("./constants");
|
|
|
25
25
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
26
26
|
/** Компонент ссылка */
|
|
27
27
|
function Link(_a) {
|
|
28
|
+
var _b, _c;
|
|
28
29
|
var {
|
|
29
30
|
text = '',
|
|
30
31
|
className,
|
|
31
|
-
href = '#',
|
|
32
|
-
target = '_blank',
|
|
33
|
-
download,
|
|
34
|
-
onClick,
|
|
35
32
|
textMode = constants_1.TEXT_MODE.Default,
|
|
36
33
|
size = constants_1.SIZE.S,
|
|
37
34
|
appearance = constants_1.APPEARANCE.Primary,
|
|
38
35
|
insideText = false,
|
|
39
|
-
truncateVariant
|
|
36
|
+
truncateVariant,
|
|
37
|
+
as
|
|
40
38
|
} = _a,
|
|
41
|
-
rest = __rest(_a, ["text", "className", "
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
rest = __rest(_a, ["text", "className", "textMode", "size", "appearance", "insideText", "truncateVariant", "as"]);
|
|
40
|
+
const Component = as || 'a';
|
|
41
|
+
let fallbackProps;
|
|
42
|
+
if (Component === 'a') {
|
|
43
|
+
/**
|
|
44
|
+
* Обратно совместимые изменения с предыдущей версией.
|
|
45
|
+
*/
|
|
46
|
+
fallbackProps = Object.assign({
|
|
47
|
+
target: (_b = rest === null || rest === void 0 ? void 0 : rest.target) !== null && _b !== void 0 ? _b : constants_1.TARGET.Blank,
|
|
48
|
+
href: (_c = rest.href) !== null && _c !== void 0 ? _c : '#',
|
|
49
|
+
download: rest.download,
|
|
50
|
+
onClick: rest.onClick
|
|
51
|
+
}, (0, utils_1.extractSupportProps)(rest));
|
|
52
|
+
fallbackProps.rel = fallbackProps.target === constants_1.TARGET.Blank ? 'noopener noreferrer' : undefined;
|
|
53
|
+
} else {
|
|
54
|
+
fallbackProps = rest;
|
|
55
|
+
}
|
|
56
|
+
return (0, jsx_runtime_1.jsx)(Component, Object.assign({
|
|
57
|
+
className: (0, classnames_1.default)(styles_module_scss_1.default.link, className)
|
|
58
|
+
}, fallbackProps, {
|
|
49
59
|
"data-size": size,
|
|
50
60
|
"data-text-mode": textMode,
|
|
51
61
|
"data-appearance": appearance,
|
|
52
62
|
"data-inside-text": insideText || undefined,
|
|
53
|
-
rel: target === '_blank' ? 'noopener noreferrer' : undefined,
|
|
54
63
|
children: insideText ? text : (0, jsx_runtime_1.jsx)(truncate_string_1.TruncateString, {
|
|
55
64
|
text: text,
|
|
56
65
|
maxLines: 1,
|
|
@@ -1,5 +1,52 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComponentPropsWithoutRef, ElementType } from 'react';
|
|
2
|
+
import { TruncateStringProps } from '@snack-uikit/truncate-string';
|
|
3
|
+
import { ValueOf, WithSupportProps } from '@snack-uikit/utils';
|
|
2
4
|
import { APPEARANCE, SIZE, TEXT_MODE } from './constants';
|
|
3
5
|
export type Appearance = ValueOf<typeof APPEARANCE>;
|
|
4
6
|
export type Size = ValueOf<typeof SIZE>;
|
|
5
7
|
export type TextMode = ValueOf<typeof TEXT_MODE>;
|
|
8
|
+
export type BaseProps = WithSupportProps<{
|
|
9
|
+
/** Текст ссылки */
|
|
10
|
+
text?: string;
|
|
11
|
+
/** Размер
|
|
12
|
+
* @default 's'
|
|
13
|
+
*/
|
|
14
|
+
size?: Size;
|
|
15
|
+
/** Стилизует ссылку для размещения на цветном фоне
|
|
16
|
+
* @default 'primary'
|
|
17
|
+
*/
|
|
18
|
+
appearance?: Appearance;
|
|
19
|
+
/** Тип поверхности, на которой размещена ссылка
|
|
20
|
+
* @default 'default'
|
|
21
|
+
*/
|
|
22
|
+
textMode?: TextMode;
|
|
23
|
+
/** Находится ли ссылка внутри текста (и можно ли её переносить) */
|
|
24
|
+
insideText?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Вариант обрезания строки:
|
|
27
|
+
* <br> - `end` - с конца;
|
|
28
|
+
* <br> - `middle` - по середине
|
|
29
|
+
* */
|
|
30
|
+
truncateVariant?: TruncateStringProps['variant'];
|
|
31
|
+
}>;
|
|
32
|
+
export type LinkProps<T extends ElementType = 'a'> = BaseProps & {
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
* Полиморфный компонент.
|
|
36
|
+
*
|
|
37
|
+
* Оформить переданный компонент или html элемент в стиль ссылки.
|
|
38
|
+
*
|
|
39
|
+
* Список атрибутов, которые переданный компонент должен принять:
|
|
40
|
+
* <br/> - `className`
|
|
41
|
+
* <br/> - `data-size`
|
|
42
|
+
* <br/> - `data-text-mode`
|
|
43
|
+
* <br/> - `data-appearance`
|
|
44
|
+
* <br/> - `data-inside-text`
|
|
45
|
+
*
|
|
46
|
+
* @type ComponentType | ElementType
|
|
47
|
+
* @default 'a'
|
|
48
|
+
*
|
|
49
|
+
* */
|
|
50
|
+
as?: T;
|
|
51
|
+
} & Omit<ComponentPropsWithoutRef<ElementType extends T ? 'a' : T>, keyof BaseProps>;
|
|
52
|
+
export type PickLinkProps<T extends ElementType, SelectedKeys extends keyof LinkProps<T>> = Pick<LinkProps<T>, SelectedKeys> & Omit<ComponentPropsWithoutRef<ElementType extends T ? 'a' : T>, keyof BaseProps>;
|
|
@@ -1,40 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { WithSupportProps } from '@snack-uikit/utils';
|
|
4
|
-
import { Appearance, Size, TextMode } from './types';
|
|
5
|
-
export type LinkProps = WithSupportProps<{
|
|
6
|
-
/** Текст ссылки */
|
|
7
|
-
text?: string;
|
|
8
|
-
/** CSS-класс */
|
|
9
|
-
className?: string;
|
|
10
|
-
/** Ссылка */
|
|
11
|
-
href?: string;
|
|
12
|
-
/** HTML-атрибут target */
|
|
13
|
-
target?: AnchorHTMLAttributes<HTMLAnchorElement>['target'];
|
|
14
|
-
/** HTML-атрибут download */
|
|
15
|
-
download?: string;
|
|
16
|
-
/** Колбек обработки клика */
|
|
17
|
-
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
18
|
-
/** Размер
|
|
19
|
-
* @default 's'
|
|
20
|
-
*/
|
|
21
|
-
size?: Size;
|
|
22
|
-
/** Стилизует ссылку для размещения на цветном фоне
|
|
23
|
-
* @default 'primary'
|
|
24
|
-
*/
|
|
25
|
-
appearance?: Appearance;
|
|
26
|
-
/** Тип поверхности, на которой размещена ссылка
|
|
27
|
-
* @default 'default'
|
|
28
|
-
*/
|
|
29
|
-
textMode?: TextMode;
|
|
30
|
-
/** Находится ли ссылка внутри текста (и можно ли её переносить) */
|
|
31
|
-
insideText?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Вариант обрезания строки:
|
|
34
|
-
* <br> - `end` - с конца;
|
|
35
|
-
* <br> - `middle` - по середине
|
|
36
|
-
* */
|
|
37
|
-
truncateVariant?: TruncateStringProps['variant'];
|
|
38
|
-
}>;
|
|
1
|
+
import { ElementType } from 'react';
|
|
2
|
+
import { LinkProps } from './types';
|
|
39
3
|
/** Компонент ссылка */
|
|
40
|
-
export declare function Link({ text, className,
|
|
4
|
+
export declare function Link<T extends ElementType = 'a'>({ text, className, textMode, size, appearance, insideText, truncateVariant, as, ...rest }: LinkProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -13,10 +13,23 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
13
13
|
import cn from 'classnames';
|
|
14
14
|
import { TruncateString } from '@snack-uikit/truncate-string';
|
|
15
15
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
16
|
-
import { APPEARANCE, SIZE, TEXT_MODE } from './constants';
|
|
16
|
+
import { APPEARANCE, SIZE, TARGET, TEXT_MODE } from './constants';
|
|
17
17
|
import styles from './styles.module.css';
|
|
18
18
|
/** Компонент ссылка */
|
|
19
19
|
export function Link(_a) {
|
|
20
|
-
var
|
|
21
|
-
|
|
20
|
+
var _b, _c;
|
|
21
|
+
var { text = '', className, textMode = TEXT_MODE.Default, size = SIZE.S, appearance = APPEARANCE.Primary, insideText = false, truncateVariant, as } = _a, rest = __rest(_a, ["text", "className", "textMode", "size", "appearance", "insideText", "truncateVariant", "as"]);
|
|
22
|
+
const Component = as || 'a';
|
|
23
|
+
let fallbackProps;
|
|
24
|
+
if (Component === 'a') {
|
|
25
|
+
/**
|
|
26
|
+
* Обратно совместимые изменения с предыдущей версией.
|
|
27
|
+
*/
|
|
28
|
+
fallbackProps = Object.assign({ target: (_b = rest === null || rest === void 0 ? void 0 : rest.target) !== null && _b !== void 0 ? _b : TARGET.Blank, href: (_c = rest.href) !== null && _c !== void 0 ? _c : '#', download: rest.download, onClick: rest.onClick }, extractSupportProps(rest));
|
|
29
|
+
fallbackProps.rel = fallbackProps.target === TARGET.Blank ? 'noopener noreferrer' : undefined;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
fallbackProps = rest;
|
|
33
|
+
}
|
|
34
|
+
return (_jsx(Component, Object.assign({ className: cn(styles.link, className) }, fallbackProps, { "data-size": size, "data-text-mode": textMode, "data-appearance": appearance, "data-inside-text": insideText || undefined, children: insideText ? text : _jsx(TruncateString, { text: text, maxLines: 1, variant: truncateVariant }) })));
|
|
22
35
|
}
|
|
@@ -1,5 +1,52 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComponentPropsWithoutRef, ElementType } from 'react';
|
|
2
|
+
import { TruncateStringProps } from '@snack-uikit/truncate-string';
|
|
3
|
+
import { ValueOf, WithSupportProps } from '@snack-uikit/utils';
|
|
2
4
|
import { APPEARANCE, SIZE, TEXT_MODE } from './constants';
|
|
3
5
|
export type Appearance = ValueOf<typeof APPEARANCE>;
|
|
4
6
|
export type Size = ValueOf<typeof SIZE>;
|
|
5
7
|
export type TextMode = ValueOf<typeof TEXT_MODE>;
|
|
8
|
+
export type BaseProps = WithSupportProps<{
|
|
9
|
+
/** Текст ссылки */
|
|
10
|
+
text?: string;
|
|
11
|
+
/** Размер
|
|
12
|
+
* @default 's'
|
|
13
|
+
*/
|
|
14
|
+
size?: Size;
|
|
15
|
+
/** Стилизует ссылку для размещения на цветном фоне
|
|
16
|
+
* @default 'primary'
|
|
17
|
+
*/
|
|
18
|
+
appearance?: Appearance;
|
|
19
|
+
/** Тип поверхности, на которой размещена ссылка
|
|
20
|
+
* @default 'default'
|
|
21
|
+
*/
|
|
22
|
+
textMode?: TextMode;
|
|
23
|
+
/** Находится ли ссылка внутри текста (и можно ли её переносить) */
|
|
24
|
+
insideText?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Вариант обрезания строки:
|
|
27
|
+
* <br> - `end` - с конца;
|
|
28
|
+
* <br> - `middle` - по середине
|
|
29
|
+
* */
|
|
30
|
+
truncateVariant?: TruncateStringProps['variant'];
|
|
31
|
+
}>;
|
|
32
|
+
export type LinkProps<T extends ElementType = 'a'> = BaseProps & {
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
* Полиморфный компонент.
|
|
36
|
+
*
|
|
37
|
+
* Оформить переданный компонент или html элемент в стиль ссылки.
|
|
38
|
+
*
|
|
39
|
+
* Список атрибутов, которые переданный компонент должен принять:
|
|
40
|
+
* <br/> - `className`
|
|
41
|
+
* <br/> - `data-size`
|
|
42
|
+
* <br/> - `data-text-mode`
|
|
43
|
+
* <br/> - `data-appearance`
|
|
44
|
+
* <br/> - `data-inside-text`
|
|
45
|
+
*
|
|
46
|
+
* @type ComponentType | ElementType
|
|
47
|
+
* @default 'a'
|
|
48
|
+
*
|
|
49
|
+
* */
|
|
50
|
+
as?: T;
|
|
51
|
+
} & Omit<ComponentPropsWithoutRef<ElementType extends T ? 'a' : T>, keyof BaseProps>;
|
|
52
|
+
export type PickLinkProps<T extends ElementType, SelectedKeys extends keyof LinkProps<T>> = Pick<LinkProps<T>, SelectedKeys> & Omit<ComponentPropsWithoutRef<ElementType extends T ? 'a' : T>, keyof BaseProps>;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Link",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.16.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"@snack-uikit/utils": "3.8.0",
|
|
41
41
|
"classnames": "2.5.1"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "60f203360684328be8e6743048d0259574ded8b4"
|
|
44
44
|
}
|
package/src/components/Link.tsx
CHANGED
|
@@ -1,78 +1,52 @@
|
|
|
1
1
|
import cn from 'classnames';
|
|
2
|
-
import {
|
|
2
|
+
import { ElementType } from 'react';
|
|
3
3
|
|
|
4
|
-
import { TruncateString
|
|
5
|
-
import { extractSupportProps
|
|
4
|
+
import { TruncateString } from '@snack-uikit/truncate-string';
|
|
5
|
+
import { extractSupportProps } from '@snack-uikit/utils';
|
|
6
6
|
|
|
7
|
-
import { APPEARANCE, SIZE, TEXT_MODE } from './constants';
|
|
7
|
+
import { APPEARANCE, SIZE, TARGET, TEXT_MODE } from './constants';
|
|
8
8
|
import styles from './styles.module.scss';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
export type LinkProps = WithSupportProps<{
|
|
12
|
-
/** Текст ссылки */
|
|
13
|
-
text?: string;
|
|
14
|
-
/** CSS-класс */
|
|
15
|
-
className?: string;
|
|
16
|
-
/** Ссылка */
|
|
17
|
-
href?: string;
|
|
18
|
-
/** HTML-атрибут target */
|
|
19
|
-
target?: AnchorHTMLAttributes<HTMLAnchorElement>['target'];
|
|
20
|
-
/** HTML-атрибут download */
|
|
21
|
-
download?: string;
|
|
22
|
-
/** Колбек обработки клика */
|
|
23
|
-
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
24
|
-
/** Размер
|
|
25
|
-
* @default 's'
|
|
26
|
-
*/
|
|
27
|
-
size?: Size;
|
|
28
|
-
/** Стилизует ссылку для размещения на цветном фоне
|
|
29
|
-
* @default 'primary'
|
|
30
|
-
*/
|
|
31
|
-
appearance?: Appearance;
|
|
32
|
-
/** Тип поверхности, на которой размещена ссылка
|
|
33
|
-
* @default 'default'
|
|
34
|
-
*/
|
|
35
|
-
textMode?: TextMode;
|
|
36
|
-
/** Находится ли ссылка внутри текста (и можно ли её переносить) */
|
|
37
|
-
insideText?: boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Вариант обрезания строки:
|
|
40
|
-
* <br> - `end` - с конца;
|
|
41
|
-
* <br> - `middle` - по середине
|
|
42
|
-
* */
|
|
43
|
-
truncateVariant?: TruncateStringProps['variant'];
|
|
44
|
-
}>;
|
|
9
|
+
import { LinkProps } from './types';
|
|
45
10
|
|
|
46
11
|
/** Компонент ссылка */
|
|
47
|
-
export function Link({
|
|
12
|
+
export function Link<T extends ElementType = 'a'>({
|
|
48
13
|
text = '',
|
|
49
14
|
className,
|
|
50
|
-
href = '#',
|
|
51
|
-
target = '_blank',
|
|
52
|
-
download,
|
|
53
|
-
onClick,
|
|
54
15
|
textMode = TEXT_MODE.Default,
|
|
55
16
|
size = SIZE.S,
|
|
56
17
|
appearance = APPEARANCE.Primary,
|
|
57
18
|
insideText = false,
|
|
58
19
|
truncateVariant,
|
|
20
|
+
as,
|
|
59
21
|
...rest
|
|
60
|
-
}: LinkProps) {
|
|
22
|
+
}: LinkProps<T>) {
|
|
23
|
+
const Component = as || 'a';
|
|
24
|
+
|
|
25
|
+
let fallbackProps;
|
|
26
|
+
|
|
27
|
+
if (Component === 'a') {
|
|
28
|
+
/**
|
|
29
|
+
* Обратно совместимые изменения с предыдущей версией.
|
|
30
|
+
*/
|
|
31
|
+
fallbackProps = Object.assign(
|
|
32
|
+
{ target: rest?.target ?? TARGET.Blank, href: rest.href ?? '#', download: rest.download, onClick: rest.onClick },
|
|
33
|
+
extractSupportProps(rest),
|
|
34
|
+
);
|
|
35
|
+
fallbackProps.rel = fallbackProps.target === TARGET.Blank ? 'noopener noreferrer' : undefined;
|
|
36
|
+
} else {
|
|
37
|
+
fallbackProps = rest;
|
|
38
|
+
}
|
|
39
|
+
|
|
61
40
|
return (
|
|
62
|
-
<
|
|
41
|
+
<Component
|
|
63
42
|
className={cn(styles.link, className)}
|
|
64
|
-
|
|
65
|
-
target={target}
|
|
66
|
-
download={download}
|
|
67
|
-
onClick={onClick}
|
|
68
|
-
{...extractSupportProps(rest)}
|
|
43
|
+
{...fallbackProps}
|
|
69
44
|
data-size={size}
|
|
70
45
|
data-text-mode={textMode}
|
|
71
46
|
data-appearance={appearance}
|
|
72
47
|
data-inside-text={insideText || undefined}
|
|
73
|
-
rel={target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
74
48
|
>
|
|
75
49
|
{insideText ? text : <TruncateString text={text} maxLines={1} variant={truncateVariant} />}
|
|
76
|
-
</
|
|
50
|
+
</Component>
|
|
77
51
|
);
|
|
78
52
|
}
|
package/src/components/index.ts
CHANGED
package/src/components/types.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComponentPropsWithoutRef, ElementType } from 'react';
|
|
2
|
+
|
|
3
|
+
import { TruncateStringProps } from '@snack-uikit/truncate-string';
|
|
4
|
+
import { ValueOf, WithSupportProps } from '@snack-uikit/utils';
|
|
2
5
|
|
|
3
6
|
import { APPEARANCE, SIZE, TEXT_MODE } from './constants';
|
|
4
7
|
|
|
@@ -7,3 +10,55 @@ export type Appearance = ValueOf<typeof APPEARANCE>;
|
|
|
7
10
|
export type Size = ValueOf<typeof SIZE>;
|
|
8
11
|
|
|
9
12
|
export type TextMode = ValueOf<typeof TEXT_MODE>;
|
|
13
|
+
|
|
14
|
+
export type BaseProps = WithSupportProps<{
|
|
15
|
+
/** Текст ссылки */
|
|
16
|
+
text?: string;
|
|
17
|
+
/** Размер
|
|
18
|
+
* @default 's'
|
|
19
|
+
*/
|
|
20
|
+
size?: Size;
|
|
21
|
+
/** Стилизует ссылку для размещения на цветном фоне
|
|
22
|
+
* @default 'primary'
|
|
23
|
+
*/
|
|
24
|
+
appearance?: Appearance;
|
|
25
|
+
/** Тип поверхности, на которой размещена ссылка
|
|
26
|
+
* @default 'default'
|
|
27
|
+
*/
|
|
28
|
+
textMode?: TextMode;
|
|
29
|
+
/** Находится ли ссылка внутри текста (и можно ли её переносить) */
|
|
30
|
+
insideText?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Вариант обрезания строки:
|
|
33
|
+
* <br> - `end` - с конца;
|
|
34
|
+
* <br> - `middle` - по середине
|
|
35
|
+
* */
|
|
36
|
+
truncateVariant?: TruncateStringProps['variant'];
|
|
37
|
+
}>;
|
|
38
|
+
|
|
39
|
+
export type LinkProps<T extends ElementType = 'a'> = BaseProps & {
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* Полиморфный компонент.
|
|
43
|
+
*
|
|
44
|
+
* Оформить переданный компонент или html элемент в стиль ссылки.
|
|
45
|
+
*
|
|
46
|
+
* Список атрибутов, которые переданный компонент должен принять:
|
|
47
|
+
* <br/> - `className`
|
|
48
|
+
* <br/> - `data-size`
|
|
49
|
+
* <br/> - `data-text-mode`
|
|
50
|
+
* <br/> - `data-appearance`
|
|
51
|
+
* <br/> - `data-inside-text`
|
|
52
|
+
*
|
|
53
|
+
* @type ComponentType | ElementType
|
|
54
|
+
* @default 'a'
|
|
55
|
+
*
|
|
56
|
+
* */
|
|
57
|
+
as?: T;
|
|
58
|
+
} & Omit<ComponentPropsWithoutRef<ElementType extends T ? 'a' : T>, keyof BaseProps>;
|
|
59
|
+
|
|
60
|
+
export type PickLinkProps<T extends ElementType, SelectedKeys extends keyof LinkProps<T>> = Pick<
|
|
61
|
+
LinkProps<T>,
|
|
62
|
+
SelectedKeys
|
|
63
|
+
> &
|
|
64
|
+
Omit<ComponentPropsWithoutRef<ElementType extends T ? 'a' : T>, keyof BaseProps>;
|