@cloud-ru/uikit-product-card-predefined 0.8.12

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 (65) hide show
  1. package/CHANGELOG.md +830 -0
  2. package/LICENSE +201 -0
  3. package/README.md +49 -0
  4. package/dist/cjs/components/CardBanner/CardBanner.d.ts +14 -0
  5. package/dist/cjs/components/CardBanner/CardBanner.js +36 -0
  6. package/dist/cjs/components/CardBanner/index.d.ts +1 -0
  7. package/dist/cjs/components/CardBanner/index.js +17 -0
  8. package/dist/cjs/components/CardBanner/styles.module.css +33 -0
  9. package/dist/cjs/components/CardService/CardService.d.ts +7 -0
  10. package/dist/cjs/components/CardService/CardService.js +27 -0
  11. package/dist/cjs/components/CardService/index.d.ts +1 -0
  12. package/dist/cjs/components/CardService/index.js +17 -0
  13. package/dist/cjs/components/CardServiceSmall/CardServiceSmall.d.ts +14 -0
  14. package/dist/cjs/components/CardServiceSmall/CardServiceSmall.js +61 -0
  15. package/dist/cjs/components/CardServiceSmall/index.d.ts +1 -0
  16. package/dist/cjs/components/CardServiceSmall/index.js +17 -0
  17. package/dist/cjs/components/CardServiceSmall/styles.module.css +52 -0
  18. package/dist/cjs/components/CardSuggest/CardSuggest.d.ts +12 -0
  19. package/dist/cjs/components/CardSuggest/CardSuggest.js +28 -0
  20. package/dist/cjs/components/CardSuggest/constants.d.ts +4 -0
  21. package/dist/cjs/components/CardSuggest/constants.js +7 -0
  22. package/dist/cjs/components/CardSuggest/index.d.ts +1 -0
  23. package/dist/cjs/components/CardSuggest/index.js +17 -0
  24. package/dist/cjs/components/index.d.ts +4 -0
  25. package/dist/cjs/components/index.js +20 -0
  26. package/dist/cjs/index.d.ts +1 -0
  27. package/dist/cjs/index.js +17 -0
  28. package/dist/esm/components/CardBanner/CardBanner.d.ts +14 -0
  29. package/dist/esm/components/CardBanner/CardBanner.js +30 -0
  30. package/dist/esm/components/CardBanner/index.d.ts +1 -0
  31. package/dist/esm/components/CardBanner/index.js +1 -0
  32. package/dist/esm/components/CardBanner/styles.module.css +33 -0
  33. package/dist/esm/components/CardService/CardService.d.ts +7 -0
  34. package/dist/esm/components/CardService/CardService.js +24 -0
  35. package/dist/esm/components/CardService/index.d.ts +1 -0
  36. package/dist/esm/components/CardService/index.js +1 -0
  37. package/dist/esm/components/CardServiceSmall/CardServiceSmall.d.ts +14 -0
  38. package/dist/esm/components/CardServiceSmall/CardServiceSmall.js +55 -0
  39. package/dist/esm/components/CardServiceSmall/index.d.ts +1 -0
  40. package/dist/esm/components/CardServiceSmall/index.js +1 -0
  41. package/dist/esm/components/CardServiceSmall/styles.module.css +52 -0
  42. package/dist/esm/components/CardSuggest/CardSuggest.d.ts +12 -0
  43. package/dist/esm/components/CardSuggest/CardSuggest.js +25 -0
  44. package/dist/esm/components/CardSuggest/constants.d.ts +4 -0
  45. package/dist/esm/components/CardSuggest/constants.js +4 -0
  46. package/dist/esm/components/CardSuggest/index.d.ts +1 -0
  47. package/dist/esm/components/CardSuggest/index.js +1 -0
  48. package/dist/esm/components/index.d.ts +4 -0
  49. package/dist/esm/components/index.js +4 -0
  50. package/dist/esm/index.d.ts +1 -0
  51. package/dist/esm/index.js +1 -0
  52. package/package.json +52 -0
  53. package/src/components/CardBanner/CardBanner.tsx +83 -0
  54. package/src/components/CardBanner/index.ts +1 -0
  55. package/src/components/CardBanner/styles.module.scss +33 -0
  56. package/src/components/CardService/CardService.tsx +41 -0
  57. package/src/components/CardService/index.ts +1 -0
  58. package/src/components/CardServiceSmall/CardServiceSmall.tsx +140 -0
  59. package/src/components/CardServiceSmall/index.ts +1 -0
  60. package/src/components/CardServiceSmall/styles.module.scss +60 -0
  61. package/src/components/CardSuggest/CardSuggest.tsx +54 -0
  62. package/src/components/CardSuggest/constants.ts +4 -0
  63. package/src/components/CardSuggest/index.ts +1 -0
  64. package/src/components/index.ts +4 -0
  65. package/src/index.ts +1 -0
@@ -0,0 +1,140 @@
1
+ import cn from 'classnames';
2
+ import { JSXElementConstructor, KeyboardEventHandler, MouseEventHandler, useRef } from 'react';
3
+ import { useUncontrolledProp } from 'uncontrollable';
4
+
5
+ import { PromoTagPredefined, PromoTagPredefinedProps } from '@cloud-ru/uikit-product-promo-tag-predefined';
6
+ import { Card, CardProps } from '@snack-uikit/card';
7
+ import { PromoTag } from '@snack-uikit/promo-tag';
8
+ import { Favorite } from '@snack-uikit/toggles';
9
+ import { TruncateString } from '@snack-uikit/truncate-string';
10
+ import { Typography } from '@snack-uikit/typography';
11
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
12
+
13
+ import styles from './styles.module.scss';
14
+
15
+ export type CardServiceSmallProps = WithSupportProps<
16
+ Pick<CardProps, 'onClick' | 'className' | 'disabled' | 'outline' | 'href' | 'checked'> &
17
+ Required<Pick<Card.HeaderProps, 'title' | 'emblem'>> & {
18
+ truncate?: Pick<NonNullable<Card.HeaderProps['truncate']>, 'title'>;
19
+ favorite?: {
20
+ enabled: boolean;
21
+ visibilityStrategy: 'always' | 'hover';
22
+ checked?: boolean;
23
+ onChange?(value: boolean): void;
24
+ };
25
+ promoBadge?: PromoTagPredefinedProps | CardProps['promoBadge'];
26
+ }
27
+ >;
28
+
29
+ function isIconProps(
30
+ props: Card.HeaderProps['emblem'],
31
+ ): props is { icon: JSXElementConstructor<{ className?: string }> } {
32
+ return Boolean(props && 'icon' in props);
33
+ }
34
+
35
+ export function CardServiceSmall({
36
+ href,
37
+ promoBadge,
38
+ title,
39
+ emblem,
40
+ onClick,
41
+ className,
42
+ disabled,
43
+ truncate,
44
+ outline,
45
+ checked,
46
+ favorite,
47
+ ...rest
48
+ }: CardServiceSmallProps) {
49
+ const [isFavourite, setIsFavorite] = useUncontrolledProp(favorite?.checked, false, favorite?.onChange);
50
+ const favoriteRef = useRef<HTMLInputElement>(null);
51
+ const cardRef = useRef<HTMLDivElement>(null);
52
+ const Icon = isIconProps(emblem) ? emblem.icon : undefined;
53
+
54
+ const onCardKeyDown: KeyboardEventHandler = event => {
55
+ if (event.code === 'ArrowRight') {
56
+ favoriteRef.current?.focus();
57
+ }
58
+ };
59
+
60
+ const onFavoriteKeyUp: KeyboardEventHandler = event => {
61
+ event.preventDefault();
62
+
63
+ if (event.code === 'ArrowLeft') {
64
+ cardRef.current?.focus();
65
+ }
66
+
67
+ if (event.code === 'Space' || event.code === 'Enter') {
68
+ setIsFavorite(!isFavourite);
69
+ }
70
+ };
71
+
72
+ const onFavoriteClick: MouseEventHandler = event => {
73
+ event.stopPropagation();
74
+
75
+ favoriteRef.current?.blur();
76
+ };
77
+
78
+ return (
79
+ <div className={cn(styles.wrapper, className)}>
80
+ <Card
81
+ {...extractSupportProps(rest)}
82
+ href={href}
83
+ ref={cardRef}
84
+ onKeyDown={onCardKeyDown}
85
+ header={
86
+ <div className={styles.contentWrapper}>
87
+ {Icon && <Icon className={styles.icon} />}
88
+
89
+ <div className={styles.contentLayout}>
90
+ <Typography
91
+ family='sans'
92
+ size='s'
93
+ purpose='title'
94
+ className={styles.title}
95
+ data-test-id='card-service-small__title'
96
+ >
97
+ <TruncateString text={title} maxLines={truncate?.title} variant='end' />
98
+ </Typography>
99
+ </div>
100
+
101
+ {favorite && favorite.enabled && (
102
+ <div className={styles.favoriteWrapper} data-visibility-strategy={favorite.visibilityStrategy}>
103
+ <Favorite
104
+ size='m'
105
+ checked={isFavourite}
106
+ inputRef={favoriteRef}
107
+ onChange={setIsFavorite}
108
+ tabIndex={-1}
109
+ onKeyUp={onFavoriteKeyUp}
110
+ onClick={onFavoriteClick}
111
+ data-test-id='card-service-small__favorite'
112
+ icon='star'
113
+ />
114
+ </div>
115
+ )}
116
+ </div>
117
+ }
118
+ onClick={onClick}
119
+ disabled={disabled}
120
+ outline={outline}
121
+ checked={checked}
122
+ size='s'
123
+ />
124
+
125
+ {promoBadge && (
126
+ <div className={styles.promoTagWrapper}>
127
+ {typeof promoBadge === 'object' && 'variant' in promoBadge ? (
128
+ <PromoTagPredefined data-test-id='card-service-small__promo-badge' {...promoBadge} />
129
+ ) : (
130
+ <PromoTag
131
+ color='decor'
132
+ {...(typeof promoBadge === 'string' ? { text: promoBadge, appearance: 'primary' } : promoBadge)}
133
+ data-test-id='card-service-small__promo-badge'
134
+ />
135
+ )}
136
+ </div>
137
+ )}
138
+ </div>
139
+ );
140
+ }
@@ -0,0 +1 @@
1
+ export * from './CardServiceSmall';
@@ -0,0 +1,60 @@
1
+ @use '@sbercloud/figma-tokens-cloud-platform/build/scss/styles-theme-variables';
2
+
3
+ .favoriteWrapper {
4
+ flex-shrink: 0;
5
+ // stylelint-disable-next-line declaration-property-value-allowed-list
6
+ z-index: 1;
7
+
8
+ &[data-visibility-strategy='hover'] {
9
+ display: none;
10
+ }
11
+
12
+ &[data-visibility-strategy='always'] {
13
+ display: flex;
14
+ }
15
+ }
16
+
17
+ .wrapper {
18
+ position: relative;
19
+
20
+ &:hover, &:focus-within {
21
+ .favoriteWrapper {
22
+ display: flex;
23
+ }
24
+ }
25
+ }
26
+
27
+ .contentWrapper {
28
+ box-sizing: border-box;
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: space-between;
32
+ width: 100%;
33
+ height: styles-theme-variables.$dimension-4m;
34
+ gap: styles-theme-variables.$dimension-1m;
35
+ color: styles-theme-variables.$sys-neutral-text-main;
36
+ }
37
+
38
+ .contentLayout {
39
+ overflow: hidden;
40
+ display: block;
41
+ max-width: 100%;
42
+ min-width: 0;
43
+ flex-grow: 1;
44
+ }
45
+
46
+ .icon {
47
+ flex-shrink: 0;
48
+ }
49
+
50
+ .title {
51
+ display: block;
52
+ max-width: 100%;
53
+ }
54
+
55
+ .promoTagWrapper {
56
+ position: absolute;
57
+ top: -4px;
58
+ right: -4px;
59
+ display: flex;
60
+ }
@@ -0,0 +1,54 @@
1
+ import { Card, CardProps } from '@snack-uikit/card';
2
+ import { TruncateString } from '@snack-uikit/truncate-string';
3
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
4
+
5
+ import { TRUNCATE_DEFAULTS } from './constants';
6
+
7
+ export type CardSuggestProps = WithSupportProps<
8
+ Pick<CardProps, 'promoBadge' | 'onClick' | 'className' | 'disabled' | 'href'> & {
9
+ size?: 's' | 'm';
10
+ title: string;
11
+ description: string;
12
+ truncate?: {
13
+ title?: number;
14
+ description?: number;
15
+ };
16
+ }
17
+ >;
18
+
19
+ export function CardSuggest({
20
+ title,
21
+ description,
22
+ truncate,
23
+ onClick,
24
+ className,
25
+ disabled,
26
+ href,
27
+ promoBadge,
28
+ size,
29
+ ...rest
30
+ }: CardSuggestProps) {
31
+ const truncateLines = { ...TRUNCATE_DEFAULTS, ...truncate };
32
+
33
+ return (
34
+ <Card
35
+ // TODO: typescript error
36
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
37
+ // @ts-ignore
38
+ {...extractSupportProps(rest)}
39
+ size={size}
40
+ promoBadge={promoBadge}
41
+ href={href}
42
+ disabled={disabled}
43
+ header={<Card.Header title={title} truncate={{ title: truncateLines.title }} />}
44
+ onClick={onClick}
45
+ className={className}
46
+ >
47
+ <TruncateString
48
+ text={description}
49
+ maxLines={truncateLines.description}
50
+ data-test-id='card-suggest__description'
51
+ />
52
+ </Card>
53
+ );
54
+ }
@@ -0,0 +1,4 @@
1
+ export const TRUNCATE_DEFAULTS = {
2
+ title: 2,
3
+ description: 3,
4
+ };
@@ -0,0 +1 @@
1
+ export * from './CardSuggest';
@@ -0,0 +1,4 @@
1
+ export * from './CardBanner';
2
+ export * from './CardSuggest';
3
+ export * from './CardService';
4
+ export * from './CardServiceSmall';
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './components';