@cloud-ru/ds-uikit-product-header 2.1.7 → 2.1.8-preview-04e34550.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 (79) hide show
  1. package/dist/cjs/components/ListCustom/helperComponents/ContentWrapperCustom/ContentWrapperCustom.d.ts +33 -0
  2. package/dist/cjs/components/ListCustom/helperComponents/ContentWrapperCustom/ContentWrapperCustom.js +24 -0
  3. package/dist/cjs/components/ListCustom/helperComponents/ContentWrapperCustom/index.d.ts +1 -0
  4. package/dist/cjs/components/ListCustom/helperComponents/ContentWrapperCustom/index.js +17 -0
  5. package/dist/cjs/components/ListCustom/helperComponents/ContentWrapperCustom/styles.module.css +168 -0
  6. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/ListItemCustom.d.ts +6 -0
  7. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/ListItemCustom.js +42 -0
  8. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/constants.d.ts +6 -0
  9. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/constants.js +6 -0
  10. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/index.d.ts +3 -0
  11. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/index.js +19 -0
  12. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/styles.module.css +236 -0
  13. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/types.d.ts +13 -0
  14. package/dist/cjs/components/ListCustom/helperComponents/ListItemCustom/types.js +2 -0
  15. package/dist/cjs/components/ListCustom/helperComponents/ListItemGroupCustom/ListItemGroupCustom.d.ts +7 -0
  16. package/dist/cjs/components/ListCustom/helperComponents/ListItemGroupCustom/ListItemGroupCustom.js +23 -0
  17. package/dist/cjs/components/ListCustom/helperComponents/ListItemGroupCustom/index.d.ts +1 -0
  18. package/dist/cjs/components/ListCustom/helperComponents/ListItemGroupCustom/index.js +17 -0
  19. package/dist/cjs/components/ListCustom/helperComponents/ListItemGroupCustom/styles.module.css +34 -0
  20. package/dist/cjs/components/ListCustom/index.d.ts +3 -0
  21. package/dist/cjs/components/ListCustom/index.js +19 -0
  22. package/dist/cjs/components/ListCustom/renderListCustom.d.ts +4 -0
  23. package/dist/cjs/components/ListCustom/renderListCustom.js +14 -0
  24. package/dist/cjs/components/MainMenu/helperComponents/Favorites/Favorites.js +2 -3
  25. package/dist/cjs/components/UserMenu/UserMenu.js +2 -4
  26. package/dist/cjs/components/UserMenu/hooks/useThemeItem.js +1 -4
  27. package/dist/cjs/components/index.d.ts +1 -0
  28. package/dist/cjs/components/index.js +1 -0
  29. package/dist/cjs/style.css +438 -0
  30. package/dist/esm/components/ListCustom/helperComponents/ContentWrapperCustom/ContentWrapperCustom.d.ts +33 -0
  31. package/dist/esm/components/ListCustom/helperComponents/ContentWrapperCustom/ContentWrapperCustom.js +18 -0
  32. package/dist/esm/components/ListCustom/helperComponents/ContentWrapperCustom/index.d.ts +1 -0
  33. package/dist/esm/components/ListCustom/helperComponents/ContentWrapperCustom/index.js +1 -0
  34. package/dist/esm/components/ListCustom/helperComponents/ContentWrapperCustom/styles.module.css +168 -0
  35. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/ListItemCustom.d.ts +6 -0
  36. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/ListItemCustom.js +36 -0
  37. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/constants.d.ts +6 -0
  38. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/constants.js +3 -0
  39. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/index.d.ts +3 -0
  40. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/index.js +3 -0
  41. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/styles.module.css +236 -0
  42. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/types.d.ts +13 -0
  43. package/dist/esm/components/ListCustom/helperComponents/ListItemCustom/types.js +1 -0
  44. package/dist/esm/components/ListCustom/helperComponents/ListItemGroupCustom/ListItemGroupCustom.d.ts +7 -0
  45. package/dist/esm/components/ListCustom/helperComponents/ListItemGroupCustom/ListItemGroupCustom.js +17 -0
  46. package/dist/esm/components/ListCustom/helperComponents/ListItemGroupCustom/index.d.ts +1 -0
  47. package/dist/esm/components/ListCustom/helperComponents/ListItemGroupCustom/index.js +1 -0
  48. package/dist/esm/components/ListCustom/helperComponents/ListItemGroupCustom/styles.module.css +34 -0
  49. package/dist/esm/components/ListCustom/index.d.ts +3 -0
  50. package/dist/esm/components/ListCustom/index.js +3 -0
  51. package/dist/esm/components/ListCustom/renderListCustom.d.ts +4 -0
  52. package/dist/esm/components/ListCustom/renderListCustom.js +10 -0
  53. package/dist/esm/components/MainMenu/helperComponents/Favorites/Favorites.js +2 -3
  54. package/dist/esm/components/UserMenu/UserMenu.js +2 -4
  55. package/dist/esm/components/UserMenu/hooks/useThemeItem.js +1 -4
  56. package/dist/esm/components/index.d.ts +1 -0
  57. package/dist/esm/components/index.js +1 -0
  58. package/dist/esm/style.css +438 -0
  59. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  60. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  61. package/package.json +31 -28
  62. package/src/components/ListCustom/helperComponents/ContentWrapperCustom/ContentWrapperCustom.tsx +106 -0
  63. package/src/components/ListCustom/helperComponents/ContentWrapperCustom/index.ts +1 -0
  64. package/src/components/ListCustom/helperComponents/ContentWrapperCustom/styles.module.scss +176 -0
  65. package/src/components/ListCustom/helperComponents/ListItemCustom/ListItemCustom.tsx +146 -0
  66. package/src/components/ListCustom/helperComponents/ListItemCustom/constants.ts +4 -0
  67. package/src/components/ListCustom/helperComponents/ListItemCustom/index.ts +3 -0
  68. package/src/components/ListCustom/helperComponents/ListItemCustom/styles.module.scss +218 -0
  69. package/src/components/ListCustom/helperComponents/ListItemCustom/types.ts +18 -0
  70. package/src/components/ListCustom/helperComponents/ListItemGroupCustom/ListItemGroupCustom.tsx +56 -0
  71. package/src/components/ListCustom/helperComponents/ListItemGroupCustom/index.ts +1 -0
  72. package/src/components/ListCustom/helperComponents/ListItemGroupCustom/styles.module.scss +52 -0
  73. package/src/components/ListCustom/index.ts +3 -0
  74. package/src/components/ListCustom/renderListCustom.tsx +13 -0
  75. package/src/components/ListCustom/specs/readme.md +246 -0
  76. package/src/components/MainMenu/helperComponents/Favorites/Favorites.tsx +8 -3
  77. package/src/components/UserMenu/UserMenu.tsx +5 -5
  78. package/src/components/UserMenu/hooks/useThemeItem.tsx +1 -4
  79. package/src/components/index.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloud-ru/ds-uikit-product-header",
3
- "version": "2.1.7",
3
+ "version": "2.1.8-preview-04e34550.0",
4
4
  "description": "Продуктовая шапка консоли — HeaderLayout, MainMenu, UserMenu, Logo, PathBreadcrumbs и PlatformLogo.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -45,33 +45,36 @@
45
45
  "@dnd-kit/utilities": "^3.2.2",
46
46
  "classnames": "^2.5.1",
47
47
  "fuse.js": "^7.1.0",
48
- "@cloud-ru/ds-avatar": "^1.0.13",
49
- "@cloud-ru/ds-accordion": "^1.2.4",
50
- "@cloud-ru/ds-adaptive": "^1.0.2",
51
- "@cloud-ru/ds-breadcrumbs": "^1.0.33",
52
- "@cloud-ru/ds-button": "^1.0.4",
53
- "@cloud-ru/ds-divider": "^1.0.2",
54
- "@cloud-ru/ds-drag-and-drop": "^1.1.3",
55
- "@cloud-ru/ds-card": "^1.0.25",
56
- "@cloud-ru/ds-drawer": "^2.1.2",
57
- "@cloud-ru/ds-info-block": "^1.0.3",
58
- "@cloud-ru/ds-icons": "^1.6.0",
59
- "@cloud-ru/ds-locale": "^1.0.0",
60
- "@cloud-ru/ds-modal": "^2.0.3",
61
- "@cloud-ru/ds-portal-context": "^1.0.2",
62
- "@cloud-ru/ds-list": "^2.3.6",
63
- "@cloud-ru/ds-promo-tag": "^1.0.3",
64
- "@cloud-ru/ds-scroll": "^1.0.5",
65
- "@cloud-ru/ds-search": "^1.0.16",
66
- "@cloud-ru/ds-segment-control": "^1.0.15",
67
- "@cloud-ru/ds-skeleton": "^1.0.2",
68
- "@cloud-ru/ds-theme": "^2.1.0",
69
- "@cloud-ru/ds-typography": "^1.0.2",
70
- "@cloud-ru/ds-tooltip": "^1.0.13",
71
- "@cloud-ru/ds-uikit-product-card-predefined": "^4.0.13",
72
- "@cloud-ru/ds-uikit-product-switch-row": "^1.0.16",
73
- "@cloud-ru/ds-utils": "^1.2.0",
74
- "@cloud-ru/ds-uikit-product-title-clickable": "^1.0.19"
48
+ "@cloud-ru/ds-accordion": "1.2.4",
49
+ "@cloud-ru/ds-breadcrumbs": "1.0.34-preview-04e34550.0",
50
+ "@cloud-ru/ds-adaptive": "1.0.2",
51
+ "@cloud-ru/ds-avatar": "1.0.13",
52
+ "@cloud-ru/ds-divider": "1.0.2",
53
+ "@cloud-ru/ds-button": "1.0.4",
54
+ "@cloud-ru/ds-card": "1.0.25",
55
+ "@cloud-ru/ds-icons": "1.6.0",
56
+ "@cloud-ru/ds-drag-and-drop": "1.1.3",
57
+ "@cloud-ru/ds-drawer": "2.1.2",
58
+ "@cloud-ru/ds-locale": "1.0.0",
59
+ "@cloud-ru/ds-info-block": "1.0.3",
60
+ "@cloud-ru/ds-materials": "2.0.1",
61
+ "@cloud-ru/ds-list": "2.3.7-preview-04e34550.0",
62
+ "@cloud-ru/ds-modal": "2.0.3",
63
+ "@cloud-ru/ds-portal-context": "1.0.2",
64
+ "@cloud-ru/ds-promo-tag": "1.0.3",
65
+ "@cloud-ru/ds-scroll": "1.0.5",
66
+ "@cloud-ru/ds-search": "1.0.16",
67
+ "@cloud-ru/ds-segment-control": "1.0.15",
68
+ "@cloud-ru/ds-theme": "2.1.0",
69
+ "@cloud-ru/ds-skeleton": "1.0.2",
70
+ "@cloud-ru/ds-toggles": "1.1.11",
71
+ "@cloud-ru/ds-tooltip": "1.0.13",
72
+ "@cloud-ru/ds-truncate-string": "1.0.14",
73
+ "@cloud-ru/ds-typography": "1.0.2",
74
+ "@cloud-ru/ds-uikit-product-title-clickable": "1.0.19",
75
+ "@cloud-ru/ds-utils": "1.2.0",
76
+ "@cloud-ru/ds-uikit-product-switch-row": "1.0.16",
77
+ "@cloud-ru/ds-uikit-product-card-predefined": "4.0.14-preview-04e34550.0"
75
78
  },
76
79
  "publishConfig": {
77
80
  "access": "public"
@@ -0,0 +1,106 @@
1
+ import { TruncateString, TruncateStringProps } from '@cloud-ru/ds-truncate-string';
2
+ import cn from 'classnames';
3
+ import { ReactNode, useMemo } from 'react';
4
+
5
+ import styles from './styles.module.scss';
6
+
7
+ type TruncateProps = {
8
+ label?: number;
9
+ description?: number;
10
+ variant?: TruncateStringProps['variant'];
11
+ };
12
+
13
+ export type ContentWrapperCustomProps = {
14
+ /** Слот до текста */
15
+ beforeContent?: ReactNode;
16
+ /** Слот после текста */
17
+ afterContent?: ReactNode;
18
+ /** Заголовок строки / группы */
19
+ label?: string | number;
20
+ /** Аннотация справа от label */
21
+ caption?: string;
22
+ /** Описание под label */
23
+ description?: string;
24
+ /** Настройки усечения длинных строк */
25
+ truncate?: TruncateProps;
26
+ /** Готовый узел вместо структурного текста (результат `contentRender` и т.п.) */
27
+ contentNode?: ReactNode;
28
+ /** Слот справа в групповом заголовке (bulk select) */
29
+ selectButton?: ReactNode;
30
+ /** Раскладка: строка списка или заголовок группы */
31
+ layout?: 'item' | 'group';
32
+ /** Визуальный стиль подписи группы */
33
+ groupVariant?: 'subtitle' | 'subtitleTertiary';
34
+ disabled?: boolean;
35
+ className?: string;
36
+ };
37
+
38
+ const DEFAULT_TRUNCATE: TruncateProps = {
39
+ label: 1,
40
+ description: 2,
41
+ variant: 'end',
42
+ };
43
+
44
+ export function ContentWrapperCustom({
45
+ beforeContent,
46
+ afterContent,
47
+ label,
48
+ caption,
49
+ description,
50
+ truncate: truncateProp,
51
+ contentNode,
52
+ selectButton,
53
+ layout = 'item',
54
+ groupVariant = 'subtitleTertiary',
55
+ disabled,
56
+ className,
57
+ }: ContentWrapperCustomProps) {
58
+ const truncate = useMemo(
59
+ () => ({
60
+ ...DEFAULT_TRUNCATE,
61
+ ...truncateProp,
62
+ }),
63
+ [truncateProp],
64
+ );
65
+
66
+ const hasStructuredText = label !== undefined && label !== null && !contentNode;
67
+
68
+ return (
69
+ <div className={cn(styles.root, className)} data-layout={layout} data-disabled={disabled || undefined}>
70
+ {beforeContent && (
71
+ <div className={styles.centeredWrapper} aria-hidden>
72
+ <div className={styles.elementBeforeContent}>{beforeContent}</div>
73
+ </div>
74
+ )}
75
+
76
+ <div className={styles.textWrapper}>
77
+ {hasStructuredText ? (
78
+ <div className={styles.textContent}>
79
+ <div className={styles.headline}>
80
+ <div className={styles.label} data-group-variant={layout === 'group' ? groupVariant : undefined}>
81
+ <TruncateString variant={truncate.variant} text={String(label)} maxLines={truncate.label} />
82
+ </div>
83
+ {caption && layout === 'item' && <span className={styles.caption}>{caption}</span>}
84
+ </div>
85
+
86
+ {description && layout === 'item' && (
87
+ <div className={styles.description}>
88
+ <TruncateString text={description} maxLines={truncate.description} />
89
+ </div>
90
+ )}
91
+ </div>
92
+ ) : (
93
+ contentNode
94
+ )}
95
+
96
+ {selectButton && <span className={styles.selectButton}>{selectButton}</span>}
97
+ </div>
98
+
99
+ {afterContent && (
100
+ <div className={cn(styles.centeredWrapper, styles.centeredWrapperAfter)} aria-hidden>
101
+ <div className={styles.elementAfterContent}>{afterContent}</div>
102
+ </div>
103
+ )}
104
+ </div>
105
+ );
106
+ }
@@ -0,0 +1 @@
1
+ export * from './ContentWrapperCustom';
@@ -0,0 +1,176 @@
1
+ @use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
2
+ @use '@cloud-ru/ds-figma-variables/build/scss/components/list.module' as list;
3
+
4
+ // Figma contentWrapperCustom (17001:43602): gap/padding из primitive, типографика size/s.
5
+ // layout=item — строка списка; layout=group — заголовок группы (listItemGroupCustom).
6
+
7
+ .root {
8
+ display: flex;
9
+ flex: 1 0 0;
10
+ gap: base.$sn-primitive-dimension-6;
11
+ min-width: 0;
12
+ }
13
+
14
+ .centeredWrapper {
15
+ display: flex;
16
+ align-items: center;
17
+ color: base.$sn-theme-color-available-version-textTertiary;
18
+
19
+ svg {
20
+ width: 100%;
21
+ max-width: 100%;
22
+ height: 100%;
23
+ max-height: 100%;
24
+ }
25
+ }
26
+
27
+ .centeredWrapperAfter {
28
+ justify-content: flex-end;
29
+ }
30
+
31
+ .textWrapper {
32
+ display: flex;
33
+ flex: 1 0 0;
34
+ align-items: flex-start;
35
+ }
36
+
37
+ .textContent {
38
+ display: flex;
39
+ flex: 1 0 0;
40
+ flex-direction: column;
41
+ gap: list.$sn-list-anatomy-size-s-listItem-contentWrapper-textWrapper-textContent-gap;
42
+ align-items: flex-start;
43
+ justify-content: center;
44
+
45
+ padding: 0;
46
+ }
47
+
48
+ .headline {
49
+ display: flex;
50
+ align-items: center;
51
+ align-self: stretch;
52
+ justify-content: space-between;
53
+
54
+ width: 100%;
55
+ min-height: list.$sn-list-anatomy-size-s-listItem-contentWrapper-textWrapper-textContent-headline-minHeight;
56
+ }
57
+
58
+ .label {
59
+ overflow: hidden;
60
+ flex: 1 1 50%;
61
+
62
+ min-width: 0;
63
+ max-width: max-content;
64
+
65
+ color: base.$sn-theme-color-available-version-textMain;
66
+ }
67
+
68
+ .caption {
69
+ overflow: hidden;
70
+ flex: 1 1 50%;
71
+
72
+ min-width: 0;
73
+ max-width: max-content;
74
+
75
+ color: base.$sn-theme-color-available-version-textTertiary;
76
+ text-overflow: ellipsis;
77
+ white-space: nowrap;
78
+ }
79
+
80
+ .description {
81
+ color: base.$sn-theme-color-available-version-textSecondary;
82
+ }
83
+
84
+ .elementBeforeContent, .elementAfterContent {
85
+ display: flex;
86
+ }
87
+
88
+ .root[data-layout='item'] {
89
+ align-items: flex-start;
90
+ padding: base.$sn-primitive-dimension-8 base.$sn-primitive-dimension-4;
91
+
92
+ .centeredWrapper {
93
+ width: base.$sn-density-icon-s;
94
+ height: list.$sn-list-anatomy-size-s-listItem-centeredWrapper-height;
95
+ }
96
+
97
+ .elementBeforeContent, .elementAfterContent {
98
+ flex-direction: column;
99
+ align-items: flex-start;
100
+ min-width: base.$sn-density-icon-s;
101
+ height: 24px; // TODO: raw value?
102
+ }
103
+
104
+ .headline {
105
+ gap: base.$sn-primitive-dimension-4;
106
+ }
107
+
108
+ .label {
109
+ @include base.composite-var(base.$base-styles, 'sn', 'regular', 'body', 's');
110
+
111
+ display: flex;
112
+ align-items: center;
113
+ }
114
+
115
+ .caption {
116
+ @include base.composite-var(base.$base-styles, 'sn', 'thin', 'label', 's');
117
+ }
118
+
119
+ .description {
120
+ @include base.composite-var(base.$base-styles, 'sn', 'regular', 'body', 's');
121
+ }
122
+ }
123
+
124
+ .root[data-layout='group'] {
125
+ align-items: center;
126
+ min-height: base.$sn-primitive-dimension-28;
127
+
128
+ .centeredWrapper {
129
+ width: base.$sn-density-icon-s;
130
+ height: base.$sn-density-icon-s;
131
+ padding-top: list.$sn-list-anatomy-size-s-listItem-centeredWrapper-paddingVertical;
132
+ padding-bottom: list.$sn-list-anatomy-size-s-listItem-centeredWrapper-paddingVertical;
133
+ }
134
+
135
+ .elementBeforeContent, .elementAfterContent {
136
+ align-items: center;
137
+ }
138
+
139
+ .textWrapper {
140
+ gap: base.$sn-primitive-dimension-2;
141
+ align-items: center;
142
+ padding-top: list.$sn-list-anatomy-size-s-listItem-contentWrapper-paddingVertical;
143
+ padding-bottom: list.$sn-list-anatomy-size-s-listItem-contentWrapper-paddingVertical;
144
+ }
145
+
146
+ .headline {
147
+ gap: list.$sn-list-anatomy-size-s-listItem-contentWrapper-textWrapper-textContent-headline-gap;
148
+
149
+ @include base.composite-var(base.$base-styles, 'sn', 'regular', 'label', 'm');
150
+ }
151
+
152
+ .label[data-group-variant='subtitle'] {
153
+ color: base.$sn-theme-color-available-version-textMain;
154
+ }
155
+
156
+ .label[data-group-variant='subtitleTertiary'] {
157
+ color: base.$sn-theme-color-available-version-textTertiary;
158
+ }
159
+ }
160
+
161
+ .root[data-disabled] {
162
+ .textWrapper {
163
+ opacity: base.$sn-theme-effect-opacity-disabled;
164
+ }
165
+
166
+ .centeredWrapper {
167
+ opacity: base.$sn-theme-effect-opacity-disabled;
168
+ }
169
+ }
170
+
171
+ .selectButton {
172
+ display: flex;
173
+ flex-shrink: 0;
174
+ justify-content: flex-end;
175
+ margin-left: auto;
176
+ }
@@ -0,0 +1,146 @@
1
+ import { isContentItem, isPrimitiveContent, ItemContentProps, TEST_IDS } from '@cloud-ru/ds-list';
2
+ import { Checkbox } from '@cloud-ru/ds-toggles';
3
+ import cn from 'classnames';
4
+ import { CSSProperties, RefObject } from 'react';
5
+
6
+ import { ContentWrapperCustom } from '../ContentWrapperCustom';
7
+ import { SELECTION_MODE } from './constants';
8
+ import styles from './styles.module.scss';
9
+ import { ListItemCustomProps } from './types';
10
+
11
+ function resolveStructuredContent(
12
+ content: ListItemCustomProps['content'],
13
+ contentFromRender?: boolean,
14
+ ): ItemContentProps | undefined {
15
+ if (contentFromRender) {
16
+ return undefined;
17
+ }
18
+ if (isContentItem(content)) {
19
+ return content;
20
+ }
21
+ if (isPrimitiveContent(content)) {
22
+ return { label: content };
23
+ }
24
+ return undefined;
25
+ }
26
+
27
+ /**
28
+ * Кастомная оболочка строки `List`/`Droplist` (Figma `listItemCustom`).
29
+ * Маркер (single) и чекбокс (multiple) рисуются внутри по `selectionMode` / `checked` / `disabled`.
30
+ */
31
+ export function ListItemCustom({
32
+ selectionMode = SELECTION_MODE.None,
33
+ checked = false,
34
+ disabled = false,
35
+ content,
36
+ contentNode,
37
+ contentFromRender,
38
+ beforeContent,
39
+ afterContent,
40
+ dragHandle,
41
+ switchControl,
42
+ expandIcon,
43
+ onExpandIconClick,
44
+ expandIconInteractive,
45
+ inactive,
46
+ open,
47
+ isParentNode,
48
+ level = 0,
49
+ className,
50
+ itemRef,
51
+ tabIndex = -1,
52
+ style,
53
+ onClick,
54
+ onMouseDown,
55
+ onKeyDown,
56
+ onFocus,
57
+ 'data-test-id': dataTestId,
58
+ }: ListItemCustomProps) {
59
+ const structuredContent = resolveStructuredContent(content, contentFromRender);
60
+ const isSingle = selectionMode === SELECTION_MODE.Single;
61
+ const isMultiple = selectionMode === SELECTION_MODE.Multiple;
62
+
63
+ // Figma: activated-подложка только у single + checked + !disabled; multiple всегда emptyNeutral.
64
+ const stateLayerState =
65
+ isSingle && checked && !disabled && !isParentNode && !switchControl
66
+ ? 'activatedOnBackground'
67
+ : 'emptyNeutralOnBackground';
68
+
69
+ // Как в BaseItem: маркер не у parent/switch; чекбокс — только multiple без switch.
70
+ const showMarker = isSingle && checked && !isParentNode && !switchControl;
71
+ const showCheckbox = isMultiple && !switchControl;
72
+
73
+ return (
74
+ <div
75
+ className={cn(styles.itemWrapper, className)}
76
+ data-selection-mode={selectionMode}
77
+ data-inactive={inactive || undefined}
78
+ data-disabled={disabled || undefined}
79
+ data-checked={checked || undefined}
80
+ data-open={open || undefined}
81
+ >
82
+ {!disabled && <span className={styles.stateLayer} aria-hidden data-state={stateLayerState} />}
83
+ <li
84
+ data-type='outside'
85
+ role='menuitem'
86
+ data-test-id={dataTestId}
87
+ ref={itemRef as RefObject<HTMLLIElement>}
88
+ className={styles.listItem}
89
+ onClick={onClick}
90
+ onMouseDown={onMouseDown}
91
+ tabIndex={tabIndex}
92
+ data-non-pointer={(inactive && !onClick) || undefined}
93
+ data-open={open || undefined}
94
+ aria-expanded={isParentNode ? Boolean(open) : undefined}
95
+ onKeyDown={onKeyDown}
96
+ onFocus={onFocus}
97
+ style={{ '--level': level, ...style } as CSSProperties}
98
+ data-level-one={level === 1 || undefined}
99
+ data-level-more-one={level > 1 || undefined}
100
+ data-checked={checked || undefined}
101
+ data-inactive={inactive || undefined}
102
+ data-disabled={disabled || undefined}
103
+ >
104
+ {dragHandle}
105
+
106
+ {showMarker && <div className={styles.marker} aria-hidden data-disabled={disabled || undefined} />}
107
+
108
+ {showCheckbox && (
109
+ <div className={styles.checkbox}>
110
+ <Checkbox size='s' disabled={disabled} checked={checked} tabIndex={-1} />
111
+ </div>
112
+ )}
113
+
114
+ <ContentWrapperCustom
115
+ layout='item'
116
+ beforeContent={beforeContent}
117
+ afterContent={afterContent}
118
+ label={structuredContent?.label}
119
+ caption={structuredContent?.caption}
120
+ description={structuredContent?.description}
121
+ truncate={structuredContent?.truncate}
122
+ contentNode={structuredContent ? undefined : contentNode}
123
+ disabled={disabled}
124
+ />
125
+
126
+ {switchControl}
127
+
128
+ {expandIcon && (
129
+ <div className={styles.expandCenteredWrapper}>
130
+ <span
131
+ className={styles.groupIndicator}
132
+ data-open={open || undefined}
133
+ data-disabled={disabled || undefined}
134
+ data-interactive={expandIconInteractive || undefined}
135
+ data-test-id={TEST_IDS.groupIndicator}
136
+ onClick={onExpandIconClick}
137
+ aria-hidden
138
+ >
139
+ {expandIcon}
140
+ </span>
141
+ </div>
142
+ )}
143
+ </li>
144
+ </div>
145
+ );
146
+ }
@@ -0,0 +1,4 @@
1
+ import { MODE } from '@cloud-ru/ds-list';
2
+
3
+ /** Режим выбора строки — совпадает с `MODE` списка (`none` / `single` / `multiple`). */
4
+ export const SELECTION_MODE = MODE;
@@ -0,0 +1,3 @@
1
+ export * from './ListItemCustom';
2
+ export * from './constants';
3
+ export * from './types';