@cloud-ru/ds-ai-suggestion 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 (98) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +201 -0
  3. package/README.md +226 -0
  4. package/dist/cjs/AiSuggestionParent/AiSuggestionParent.d.ts +7 -0
  5. package/dist/cjs/AiSuggestionParent/AiSuggestionParent.js +107 -0
  6. package/dist/cjs/AiSuggestionParent/AiSuggestionParentChip.d.ts +26 -0
  7. package/dist/cjs/AiSuggestionParent/AiSuggestionParentChip.js +24 -0
  8. package/dist/cjs/AiSuggestionParent/animation/AnimatedExpandableItem.d.ts +12 -0
  9. package/dist/cjs/AiSuggestionParent/animation/AnimatedExpandableItem.js +24 -0
  10. package/dist/cjs/AiSuggestionParent/animation/constants.d.ts +33 -0
  11. package/dist/cjs/AiSuggestionParent/animation/constants.js +69 -0
  12. package/dist/cjs/AiSuggestionParent/animation/styles.module.css +23 -0
  13. package/dist/cjs/AiSuggestionParent/constants.d.ts +9 -0
  14. package/dist/cjs/AiSuggestionParent/constants.js +12 -0
  15. package/dist/cjs/AiSuggestionParent/context/AiSuggestionParentGroupContext.d.ts +13 -0
  16. package/dist/cjs/AiSuggestionParent/context/AiSuggestionParentGroupContext.js +25 -0
  17. package/dist/cjs/AiSuggestionParent/index.d.ts +4 -0
  18. package/dist/cjs/AiSuggestionParent/index.js +24 -0
  19. package/dist/cjs/AiSuggestionParent/styles.module.css +156 -0
  20. package/dist/cjs/AiSuggestionParent/types.d.ts +44 -0
  21. package/dist/cjs/AiSuggestionParent/types.js +2 -0
  22. package/dist/cjs/AiSuggestionParent/utils/hasExclusiveParentGroup.d.ts +2 -0
  23. package/dist/cjs/AiSuggestionParent/utils/hasExclusiveParentGroup.js +7 -0
  24. package/dist/cjs/AiSuggestionParent/utils/itemGuards.d.ts +3 -0
  25. package/dist/cjs/AiSuggestionParent/utils/itemGuards.js +11 -0
  26. package/dist/cjs/AiSuggestionSimple/AiSuggestionSimple.d.ts +18 -0
  27. package/dist/cjs/AiSuggestionSimple/AiSuggestionSimple.js +17 -0
  28. package/dist/cjs/AiSuggestionSimple/constants.d.ts +18 -0
  29. package/dist/cjs/AiSuggestionSimple/constants.js +21 -0
  30. package/dist/cjs/AiSuggestionSimple/index.d.ts +3 -0
  31. package/dist/cjs/AiSuggestionSimple/index.js +24 -0
  32. package/dist/cjs/AiSuggestionSimple/styles.module.css +138 -0
  33. package/dist/cjs/AiSuggestionSimple/types.d.ts +5 -0
  34. package/dist/cjs/AiSuggestionSimple/types.js +2 -0
  35. package/dist/cjs/AiSuggestionSimple/utils.d.ts +2 -0
  36. package/dist/cjs/AiSuggestionSimple/utils.js +7 -0
  37. package/dist/cjs/index.d.ts +2 -0
  38. package/dist/cjs/index.js +18 -0
  39. package/dist/cjs/package.json +3 -0
  40. package/dist/cjs/style.css +317 -0
  41. package/dist/esm/AiSuggestionParent/AiSuggestionParent.d.ts +7 -0
  42. package/dist/esm/AiSuggestionParent/AiSuggestionParent.js +101 -0
  43. package/dist/esm/AiSuggestionParent/AiSuggestionParentChip.d.ts +26 -0
  44. package/dist/esm/AiSuggestionParent/AiSuggestionParentChip.js +18 -0
  45. package/dist/esm/AiSuggestionParent/animation/AnimatedExpandableItem.d.ts +12 -0
  46. package/dist/esm/AiSuggestionParent/animation/AnimatedExpandableItem.js +17 -0
  47. package/dist/esm/AiSuggestionParent/animation/constants.d.ts +33 -0
  48. package/dist/esm/AiSuggestionParent/animation/constants.js +63 -0
  49. package/dist/esm/AiSuggestionParent/animation/styles.module.css +23 -0
  50. package/dist/esm/AiSuggestionParent/constants.d.ts +9 -0
  51. package/dist/esm/AiSuggestionParent/constants.js +9 -0
  52. package/dist/esm/AiSuggestionParent/context/AiSuggestionParentGroupContext.d.ts +13 -0
  53. package/dist/esm/AiSuggestionParent/context/AiSuggestionParentGroupContext.js +21 -0
  54. package/dist/esm/AiSuggestionParent/index.d.ts +4 -0
  55. package/dist/esm/AiSuggestionParent/index.js +4 -0
  56. package/dist/esm/AiSuggestionParent/styles.module.css +156 -0
  57. package/dist/esm/AiSuggestionParent/types.d.ts +44 -0
  58. package/dist/esm/AiSuggestionParent/types.js +1 -0
  59. package/dist/esm/AiSuggestionParent/utils/hasExclusiveParentGroup.d.ts +2 -0
  60. package/dist/esm/AiSuggestionParent/utils/hasExclusiveParentGroup.js +4 -0
  61. package/dist/esm/AiSuggestionParent/utils/itemGuards.d.ts +3 -0
  62. package/dist/esm/AiSuggestionParent/utils/itemGuards.js +7 -0
  63. package/dist/esm/AiSuggestionSimple/AiSuggestionSimple.d.ts +18 -0
  64. package/dist/esm/AiSuggestionSimple/AiSuggestionSimple.js +11 -0
  65. package/dist/esm/AiSuggestionSimple/constants.d.ts +18 -0
  66. package/dist/esm/AiSuggestionSimple/constants.js +18 -0
  67. package/dist/esm/AiSuggestionSimple/index.d.ts +3 -0
  68. package/dist/esm/AiSuggestionSimple/index.js +3 -0
  69. package/dist/esm/AiSuggestionSimple/styles.module.css +138 -0
  70. package/dist/esm/AiSuggestionSimple/types.d.ts +5 -0
  71. package/dist/esm/AiSuggestionSimple/types.js +1 -0
  72. package/dist/esm/AiSuggestionSimple/utils.d.ts +2 -0
  73. package/dist/esm/AiSuggestionSimple/utils.js +4 -0
  74. package/dist/esm/index.d.ts +2 -0
  75. package/dist/esm/index.js +2 -0
  76. package/dist/esm/style.css +317 -0
  77. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  78. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  79. package/package.json +45 -0
  80. package/src/AiSuggestionParent/AiSuggestionParent.tsx +257 -0
  81. package/src/AiSuggestionParent/AiSuggestionParentChip.tsx +79 -0
  82. package/src/AiSuggestionParent/animation/AnimatedExpandableItem.tsx +53 -0
  83. package/src/AiSuggestionParent/animation/constants.ts +77 -0
  84. package/src/AiSuggestionParent/animation/styles.module.scss +25 -0
  85. package/src/AiSuggestionParent/constants.ts +10 -0
  86. package/src/AiSuggestionParent/context/AiSuggestionParentGroupContext.tsx +44 -0
  87. package/src/AiSuggestionParent/index.ts +4 -0
  88. package/src/AiSuggestionParent/styles.module.scss +197 -0
  89. package/src/AiSuggestionParent/types.ts +49 -0
  90. package/src/AiSuggestionParent/utils/hasExclusiveParentGroup.ts +6 -0
  91. package/src/AiSuggestionParent/utils/itemGuards.ts +10 -0
  92. package/src/AiSuggestionSimple/AiSuggestionSimple.tsx +72 -0
  93. package/src/AiSuggestionSimple/constants.ts +21 -0
  94. package/src/AiSuggestionSimple/index.ts +3 -0
  95. package/src/AiSuggestionSimple/styles.module.scss +166 -0
  96. package/src/AiSuggestionSimple/types.ts +7 -0
  97. package/src/AiSuggestionSimple/utils.ts +6 -0
  98. package/src/index.ts +2 -0
@@ -0,0 +1,197 @@
1
+ @use 'sass:map';
2
+ @use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
3
+
4
+ $sizes: 's', 'm';
5
+
6
+ $typography: (
7
+ 's': base.$sn-regular-label-m,
8
+ 'm': base.$sn-regular-label-l,
9
+ );
10
+
11
+ $chip-heights: (
12
+ 's': base.$sn-primitive-dimension-32,
13
+ 'm': base.$sn-primitive-dimension-40,
14
+ );
15
+
16
+ $chip-padding-inline: (
17
+ 's': base.$sn-primitive-dimension-4,
18
+ 'm': base.$sn-primitive-dimension-8,
19
+ );
20
+
21
+ // Правый отступ LabelContainer меньше левого: шеврон визуально прижат к тексту
22
+ $label-padding-inline-end: (
23
+ 's': base.$sn-primitive-dimension-0,
24
+ 'm': base.$sn-primitive-dimension-2,
25
+ );
26
+
27
+ $icon-size: base.$sn-density-size-icon-s;
28
+
29
+ $outline-transition-duration: 120ms;
30
+ $parent-transition-duration: 450ms;
31
+ $parent-transition-regular:
32
+ background-color $parent-transition-duration cubic-bezier(1, 0, 0.26, 0.7),
33
+ border-color $parent-transition-duration cubic-bezier(1, 0, 0.26, 0.7),
34
+ color $parent-transition-duration cubic-bezier(1, 0, 0.26, 0.7),
35
+ outline-color $outline-transition-duration ease;
36
+
37
+ $parent-transition-activated:
38
+ background-color $parent-transition-duration cubic-bezier(0.7, 0.26, 0, 1.58),
39
+ border-color $parent-transition-duration cubic-bezier(0.7, 0.26, 0, 1.58),
40
+ color $parent-transition-duration cubic-bezier(0.7, 0.26, 0, 1.58),
41
+ outline-color $outline-transition-duration ease;
42
+
43
+ $chevron-transition-regular: transform $parent-transition-duration cubic-bezier(1, 0, 0.26, 0.7);
44
+ $chevron-transition-activated: transform $parent-transition-duration cubic-bezier(0.7, 0.26, 0, 1.58);
45
+
46
+ .root {
47
+ display: flex;
48
+ flex-wrap: wrap;
49
+ row-gap: base.$sn-primitive-dimension-4;
50
+ align-items: center;
51
+
52
+ min-width: 0;
53
+ max-width: 100%;
54
+ }
55
+
56
+ .root[data-flatten] {
57
+ display: contents;
58
+ }
59
+
60
+ .label {
61
+ overflow: hidden;
62
+ text-overflow: ellipsis;
63
+ white-space: nowrap;
64
+ }
65
+
66
+ .icon {
67
+ color: currentcolor;
68
+ }
69
+
70
+ .chevron {
71
+ display: flex;
72
+ flex-shrink: 0;
73
+ align-items: center;
74
+ justify-content: center;
75
+
76
+ width: $icon-size;
77
+ height: $icon-size;
78
+
79
+ color: currentcolor;
80
+ }
81
+
82
+ .chip {
83
+ cursor: pointer;
84
+
85
+ position: relative;
86
+
87
+ display: inline-flex;
88
+ flex-shrink: 0;
89
+ align-items: center;
90
+ justify-content: center;
91
+
92
+ box-sizing: border-box;
93
+ margin: 0;
94
+ padding: 0;
95
+ border: base.$sn-primitive-strokeWeight-strokeRegular solid
96
+ base.$sn-theme-color-material-stateLayer-neutral-border-default-borderColor;
97
+ border-radius: base.$sn-primitive-dimension-full;
98
+
99
+ font-family: inherit;
100
+ text-decoration: none;
101
+
102
+ background-color: base.$sn-theme-color-neutral-background1Level;
103
+ outline: 0;
104
+ outline-offset: 0;
105
+
106
+ transition: $parent-transition-regular;
107
+
108
+ .icon,
109
+ .label,
110
+ .chevron {
111
+ color: base.$sn-theme-color-neutral-text;
112
+ }
113
+
114
+ &:disabled {
115
+ cursor: not-allowed;
116
+ opacity: base.$sn-theme-effect-opacity-disabled;
117
+ }
118
+
119
+ &:not(:disabled):focus-visible {
120
+ outline: base.$sn-primitive-strokeWeight-strokeSemiBold solid base.$sn-theme-color-primary-accent;
121
+ outline-offset: 0;
122
+ }
123
+
124
+ &[data-activated] {
125
+ border-color: base.$sn-theme-color-primary-accent;
126
+ background-color: base.$sn-theme-color-primary-background1Level;
127
+ transition: $parent-transition-activated;
128
+
129
+ .icon,
130
+ .label,
131
+ .chevron {
132
+ color: base.$sn-theme-color-primary-text;
133
+ }
134
+
135
+ @media (hover: hover) {
136
+ &:hover:not(:disabled) {
137
+ border-color: color-mix(in srgb, base.$sn-theme-color-primary-accent 80%, transparent);
138
+ background-color: base.$sn-theme-color-primary-background2Level;
139
+ }
140
+ }
141
+ }
142
+
143
+ &:not([data-activated], :disabled) {
144
+ @media (hover: hover) {
145
+ &:hover {
146
+ border-color: base.$sn-theme-color-material-stateLayer-neutral-border-hovered-borderColor;
147
+ }
148
+ }
149
+ }
150
+
151
+ @each $size in $sizes {
152
+ &[data-size='#{$size}'] {
153
+ @include base.composite-var($typography, $size);
154
+
155
+ height: map.get($chip-heights, $size);
156
+ padding-inline: map.get($chip-padding-inline, $size);
157
+
158
+ .icon {
159
+ display: flex;
160
+ flex-shrink: 0;
161
+ align-items: center;
162
+ justify-content: center;
163
+
164
+ width: $icon-size;
165
+ height: $icon-size;
166
+
167
+ > svg {
168
+ display: block;
169
+ width: 100%;
170
+ height: 100%;
171
+ }
172
+ }
173
+
174
+ .labelContainer {
175
+ padding-inline: map.get($chip-padding-inline, $size) map.get($label-padding-inline-end, $size);
176
+ }
177
+ }
178
+ }
179
+ }
180
+
181
+ .labelContainer {
182
+ display: inline-flex;
183
+ align-items: center;
184
+ justify-content: center;
185
+ }
186
+
187
+ .chevronIcon {
188
+ display: block;
189
+ max-width: 100%;
190
+ max-height: 100%;
191
+ transition: $chevron-transition-regular;
192
+ }
193
+
194
+ .chip[data-activated] .chevronIcon {
195
+ transform: rotate(90deg);
196
+ transition: $chevron-transition-activated;
197
+ }
@@ -0,0 +1,49 @@
1
+ import { WithSupportProps } from '@cloud-ru/ds-utils';
2
+ import { MouseEvent, ReactNode } from 'react';
3
+
4
+ import { Size } from '../AiSuggestionSimple/types';
5
+ import { CHILD_TYPE } from './constants';
6
+
7
+ export type AiSuggestionParentProps = WithSupportProps<{
8
+ /** Текст на триггере */
9
+ label?: string;
10
+ /** Иконка слева от текста */
11
+ icon?: ReactNode;
12
+ /** Размер (Figma: Mobile Off → `s`, Mobile On → `m`) */
13
+ size?: Size;
14
+ /** Блокирует взаимодействие */
15
+ disabled?: boolean;
16
+ /** Controlled — раскрыт (Figma: Activated=On) */
17
+ expanded?: boolean;
18
+ /** Uncontrolled — initial expanded */
19
+ defaultExpanded?: boolean;
20
+ /** Колбэк toggle (controlled и uncontrolled) */
21
+ onExpandedChange?(expanded: boolean): void;
22
+ /** Вложенные подсказки и группы */
23
+ items?: AiSuggestionParentItem[];
24
+ /** Колбэк клика по вложенной подсказке */
25
+ onItemClick?(index: number, event: MouseEvent<HTMLButtonElement>): void;
26
+ /** Дополнительный CSS-класс */
27
+ className?: string;
28
+ }>;
29
+
30
+ export type AiSuggestionParentSuggestionItem = {
31
+ type?: typeof CHILD_TYPE.Suggestion;
32
+ key?: string;
33
+ items?: never;
34
+ label?: string;
35
+ icon?: ReactNode;
36
+ disabled?: boolean;
37
+ onClick?(event: MouseEvent<HTMLButtonElement>): void;
38
+ };
39
+
40
+ export type AiSuggestionParentNestedItem = {
41
+ type?: typeof CHILD_TYPE.Parent;
42
+ key?: string;
43
+ label?: string;
44
+ icon?: ReactNode;
45
+ disabled?: boolean;
46
+ items?: AiSuggestionParentItem[];
47
+ };
48
+
49
+ export type AiSuggestionParentItem = AiSuggestionParentSuggestionItem | AiSuggestionParentNestedItem;
@@ -0,0 +1,6 @@
1
+ import { AiSuggestionParentItem } from '../types';
2
+ import { isNestedItem } from './itemGuards';
3
+
4
+ export function hasExclusiveParentGroup(items: AiSuggestionParentItem[]): boolean {
5
+ return items.filter(isNestedItem).length >= 2;
6
+ }
@@ -0,0 +1,10 @@
1
+ import { CHILD_TYPE } from '../constants';
2
+ import { AiSuggestionParentItem, AiSuggestionParentNestedItem, AiSuggestionParentSuggestionItem } from '../types';
3
+
4
+ export function isNestedItem(item: AiSuggestionParentItem): item is AiSuggestionParentNestedItem {
5
+ return item.type === CHILD_TYPE.Parent || item.items !== undefined;
6
+ }
7
+
8
+ export function isSuggestionItem(item: AiSuggestionParentItem): item is AiSuggestionParentSuggestionItem {
9
+ return !isNestedItem(item);
10
+ }
@@ -0,0 +1,72 @@
1
+ import { extractSupportProps, WithSupportProps } from '@cloud-ru/ds-utils';
2
+ import cn from 'classnames';
3
+ import { ButtonHTMLAttributes, ReactNode } from 'react';
4
+
5
+ import { APPEARANCE, SIZE, TEST_IDS } from './constants';
6
+ import styles from './styles.module.scss';
7
+ import { Appearance, Size } from './types';
8
+ import { getLayerState } from './utils';
9
+
10
+ export type AiSuggestionSimpleProps = WithSupportProps<{
11
+ /** Текст подсказки */
12
+ label?: string;
13
+ /** Иконка слева от текста */
14
+ icon?: ReactNode;
15
+ /** Внешний вид (Figma: Primary On/Off) */
16
+ appearance?: Appearance;
17
+ /** Размер (Figma: Mobile Off → `s`, Mobile On → `m`) */
18
+ size?: Size;
19
+ /** Блокирует взаимодействие */
20
+ disabled?: boolean;
21
+ /** Дополнительный CSS-класс */
22
+ className?: string;
23
+ }> &
24
+ Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'tabIndex' | 'onClick'>;
25
+
26
+ export function AiSuggestionSimple({
27
+ label = 'Label text',
28
+ icon,
29
+ appearance = APPEARANCE.Neutral,
30
+ size = SIZE.S,
31
+ disabled = false,
32
+ tabIndex,
33
+ onClick,
34
+ className,
35
+ ...rest
36
+ }: AiSuggestionSimpleProps) {
37
+ const layerState = getLayerState(appearance);
38
+ const rootTestId = rest['data-test-id'] ?? TEST_IDS.root;
39
+
40
+ return (
41
+ <button
42
+ type='button'
43
+ className={cn(styles.chip, className)}
44
+ {...extractSupportProps(rest)}
45
+ data-size={size}
46
+ data-appearance={appearance}
47
+ data-disabled={disabled || undefined}
48
+ data-test-id={rootTestId}
49
+ disabled={disabled}
50
+ tabIndex={tabIndex}
51
+ onClick={disabled ? undefined : onClick}
52
+ >
53
+ <span className={styles.stateLayer} aria-hidden data-state={layerState} />
54
+
55
+ <span className={styles.content}>
56
+ {icon && (
57
+ <span className={styles.icon} data-test-id={TEST_IDS.icon}>
58
+ {icon}
59
+ </span>
60
+ )}
61
+
62
+ {label && (
63
+ <span className={styles.labelContainer}>
64
+ <span className={styles.label} data-test-id={TEST_IDS.label}>
65
+ {label}
66
+ </span>
67
+ </span>
68
+ )}
69
+ </span>
70
+ </button>
71
+ );
72
+ }
@@ -0,0 +1,21 @@
1
+ export const SIZE = {
2
+ S: 's',
3
+ M: 'm',
4
+ } as const;
5
+
6
+ export const APPEARANCE = {
7
+ Primary: 'primary',
8
+ Neutral: 'neutral',
9
+ } as const;
10
+
11
+ export const TEST_IDS = {
12
+ root: 'ai-suggestion-simple',
13
+ chip: 'ai-suggestion-simple__chip',
14
+ icon: 'ai-suggestion-simple__icon',
15
+ label: 'ai-suggestion-simple__label',
16
+ } as const;
17
+
18
+ export const LAYER_STATE = {
19
+ ActivatedOnBackground: 'activatedOnBackground',
20
+ EmptyNeutralOnBackground: 'emptyNeutralOnBackground',
21
+ } as const;
@@ -0,0 +1,3 @@
1
+ export * from './AiSuggestionSimple';
2
+ export { APPEARANCE, LAYER_STATE, SIZE, TEST_IDS as AI_SUGGESTION_SIMPLE_TEST_IDS } from './constants';
3
+ export * from './types';
@@ -0,0 +1,166 @@
1
+ @use 'sass:map';
2
+ @use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
3
+ @use '@cloud-ru/ds-materials' as m;
4
+
5
+ $sizes: 's', 'm';
6
+ $appearances: 'primary', 'neutral';
7
+
8
+ $typography: (
9
+ 's': base.$sn-regular-label-m,
10
+ 'm': base.$sn-regular-label-l,
11
+ );
12
+
13
+ $chip-heights: (
14
+ 's': base.$sn-primitive-dimension-32,
15
+ 'm': base.$sn-primitive-dimension-40,
16
+ );
17
+
18
+ $chip-padding-inline: (
19
+ 's': base.$sn-primitive-dimension-4,
20
+ 'm': base.$sn-primitive-dimension-8,
21
+ );
22
+
23
+ $icon-size: base.$sn-density-size-icon-s;
24
+
25
+ $chip-interaction-transition-duration: 120ms;
26
+ $chip-interaction-transition:
27
+ background-color $chip-interaction-transition-duration ease,
28
+ border-color $chip-interaction-transition-duration ease,
29
+ color $chip-interaction-transition-duration ease;
30
+
31
+ .label {
32
+ overflow: hidden;
33
+ text-overflow: ellipsis;
34
+ white-space: nowrap;
35
+ }
36
+
37
+ .icon {
38
+ color: currentcolor;
39
+ }
40
+
41
+ .chip {
42
+ cursor: pointer;
43
+
44
+ position: relative;
45
+
46
+ display: inline-flex;
47
+ align-items: center;
48
+ justify-content: center;
49
+
50
+ box-sizing: border-box;
51
+ margin: 0;
52
+ padding: 0;
53
+ border: base.$sn-primitive-strokeWeight-strokeRegular solid transparent;
54
+ border-radius: base.$sn-primitive-dimension-full;
55
+
56
+ font-family: inherit;
57
+ text-decoration: none;
58
+
59
+ background-color: transparent;
60
+ outline: 0;
61
+ outline-offset: 0;
62
+
63
+ transition: $chip-interaction-transition;
64
+
65
+ &:disabled,
66
+ &[data-disabled] {
67
+ cursor: not-allowed;
68
+ opacity: base.$sn-theme-effect-opacity-disabled;
69
+ }
70
+
71
+ &:focus-visible {
72
+ background-color: transparent;
73
+ outline: base.$sn-primitive-strokeWeight-strokeSemiBold solid base.$sn-theme-color-primary-accent;
74
+ outline-offset: base.$sn-primitive-dimension-2;
75
+ }
76
+
77
+ @each $size in $sizes {
78
+ &[data-size='#{$size}'] {
79
+ @include base.composite-var($typography, $size);
80
+
81
+ height: map.get($chip-heights, $size);
82
+ padding-inline: map.get($chip-padding-inline, $size);
83
+
84
+ .icon {
85
+ display: flex;
86
+ flex-shrink: 0;
87
+ align-items: center;
88
+ justify-content: center;
89
+
90
+ width: $icon-size;
91
+ height: $icon-size;
92
+
93
+ > svg {
94
+ max-width: 100%;
95
+ max-height: 100%;
96
+ }
97
+ }
98
+
99
+ .labelContainer {
100
+ padding-inline: map.get($chip-padding-inline, $size);
101
+ }
102
+ }
103
+ }
104
+
105
+ @each $appearance in $appearances {
106
+ &:focus-visible {
107
+ background-color: var(--sn-theme-color-#{$appearance}-background1Level);
108
+ }
109
+
110
+ &[data-appearance='#{$appearance}'] {
111
+ @if $appearance == 'neutral' {
112
+ border-color: base.$sn-theme-color-material-stateLayer-neutral-border-default-borderColor;
113
+
114
+ .icon,
115
+ .label {
116
+ color: base.$sn-theme-color-neutral-text;
117
+ }
118
+
119
+ @media (hover: hover) {
120
+ &:hover:not(:disabled, [data-disabled]) {
121
+ border-color: base.$sn-theme-color-material-stateLayer-neutral-border-hovered-borderColor;
122
+ background-color: base.$sn-theme-color-neutral-background1Level;
123
+
124
+ .icon,
125
+ .label {
126
+ color: base.$sn-theme-color-available-version-textMain;
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ @else {
133
+ border-color: base.$sn-theme-color-material-stateLayer-activated-default-filled;
134
+
135
+ .icon,
136
+ .label {
137
+ color: base.$sn-theme-color-primary-text;
138
+ }
139
+
140
+ @media (hover: hover) {
141
+ &:hover:not(:disabled, [data-disabled]) {
142
+ border-color: base.$sn-theme-color-material-stateLayer-activated-hovered-filled;
143
+ background-color: base.$sn-theme-color-primary-background1Level;
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+
151
+ .content {
152
+ position: relative;
153
+ z-index: 1;
154
+
155
+ display: inline-flex;
156
+ align-items: center;
157
+ justify-content: center;
158
+
159
+ min-width: 0;
160
+ }
161
+
162
+ .labelContainer {
163
+ display: inline-flex;
164
+ align-items: center;
165
+ justify-content: center;
166
+ }
@@ -0,0 +1,7 @@
1
+ import { ValueOf } from '@cloud-ru/ds-utils';
2
+
3
+ import { APPEARANCE, LAYER_STATE, SIZE } from './constants';
4
+
5
+ export type Size = ValueOf<typeof SIZE>;
6
+ export type Appearance = ValueOf<typeof APPEARANCE>;
7
+ export type LayerState = ValueOf<typeof LAYER_STATE>;
@@ -0,0 +1,6 @@
1
+ import { APPEARANCE, LAYER_STATE } from './constants';
2
+ import { Appearance, LayerState } from './types';
3
+
4
+ export function getLayerState(appearance: Appearance): LayerState {
5
+ return appearance === APPEARANCE.Primary ? LAYER_STATE.ActivatedOnBackground : LAYER_STATE.EmptyNeutralOnBackground;
6
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './AiSuggestionParent';
2
+ export * from './AiSuggestionSimple';