@snack-uikit/list 0.2.2-preview-006b34c3.0 → 0.3.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 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.3.0 (2024-02-07)
7
+
8
+
9
+ ### Features
10
+
11
+ * **FF-4241:** add itemWrapRender ([4efb798](https://github.com/cloud-ru-tech/snack-uikit/commit/4efb79897b8ef129e89bf62a9332b93d79648bbf))
12
+
13
+
14
+
15
+
16
+
6
17
  ## 0.2.1 (2024-02-05)
7
18
 
8
19
  ### Only dependencies have been changed
@@ -37,5 +37,5 @@ export function AccordionItem(_a) {
37
37
  toggleOpenCollapsedItems === null || toggleOpenCollapsedItems === void 0 ? void 0 : toggleOpenCollapsedItems(id !== null && id !== void 0 ? id : '');
38
38
  (_a = option.onClick) === null || _a === void 0 ? void 0 : _a.call(option, e);
39
39
  };
40
- return (_jsx("li", { style: { listStyleType: 'none' }, children: _jsx(CollapseBlockPrivate, { header: _jsx(BaseItem, Object.assign({}, option, { id: id, disabled: disabled, expandIcon: open ? _jsx(ChevronUpSVG, {}) : _jsx(ChevronDownSVG, {}), onClick: handleItemClick, isParentNode: true, onKeyDown: handleKeyDown, indeterminate: isIndeterminate && !checked, onSelect: !disabled ? handleOnSelect : undefined })), expanded: open, "data-test-id": `list__accordion-item-${id}`, children: _jsx(CollapseContext.Provider, { value: { level: level + 1 }, children: itemsJSX }) }) }));
40
+ return (_jsx(CollapseBlockPrivate, { header: _jsx(BaseItem, Object.assign({}, option, { id: id, disabled: disabled, expandIcon: open ? _jsx(ChevronUpSVG, {}) : _jsx(ChevronDownSVG, {}), onClick: handleItemClick, isParentNode: true, onKeyDown: handleKeyDown, indeterminate: isIndeterminate && !checked, onSelect: !disabled ? handleOnSelect : undefined })), expanded: open, "data-test-id": `list__accordion-item-${id}`, children: _jsx(CollapseContext.Provider, { value: { level: level + 1 }, children: itemsJSX }) }));
41
41
  }
@@ -68,7 +68,7 @@ export function BaseItem(_a) {
68
68
  e.stopPropagation();
69
69
  };
70
70
  const props = extractSupportProps(rest);
71
- const item = (_jsx("li", { role: 'menuitem', "data-test-id": props['data-test-id'] || 'list__base-item_' + id, children: _jsxs("button", { ref: itemRef, className: cn(commonStyles.listItem, styles.droplistItem, className), "data-size": size, onClick: handleItemClick, tabIndex: -1, "data-non-pointer": inactive && !onClick, "data-inactive": inactive || undefined, "data-checked": (isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined, "data-variant": mode || undefined, "data-open": open || undefined, disabled: disabled, onKeyDown: handleItemKeyDown, onFocus: handleItemFocus, style: { '--level': level }, children: [!switchProp && isSelectionSingle && marker && !isParentNode && interactive && (_jsx("div", { className: styles.markerContainer, "data-test-id": 'list__base-item-marker' })), !switchProp && isSelectionMultiple && interactive && (_jsx("div", { className: styles.checkbox, children: _jsx(Checkbox, { size: CHECKBOX_SIZE_MAP[size !== null && size !== void 0 ? size : 's'], disabled: disabled, tabIndex: -1, onChange: handleCheckboxChange, checked: isChecked, "data-test-id": 'list__base-item-checkbox', onClick: handleCheckboxClick, indeterminate: indeterminate }) })), beforeContent && _jsx("div", { className: styles.beforeContent, children: beforeContent }), _jsxs("div", { className: styles.content, children: [_jsxs("div", { className: styles.headline, children: [_jsx("span", { className: styles.option, children: _jsx(TruncateString, { text: option, maxLines: 1 }) }), caption && _jsx("span", { className: styles.caption, children: caption })] }), description && (_jsx("div", { className: styles.description, children: _jsx(TruncateString, { text: description, maxLines: 2 }) }))] }), afterContent, switchProp && interactive && (_jsx(Switch, { disabled: disabled, checked: isChecked, "data-test-id": 'list__base-item-switch' })), !switchProp && expandIcon && _jsx("span", { className: styles.expandableIcon, children: expandIcon })] }) }));
71
+ const item = (_jsxs("li", { role: 'menuitem', "data-test-id": props['data-test-id'] || 'list__base-item_' + id, ref: itemRef, className: cn(commonStyles.listItem, styles.droplistItem, className), "data-size": size, onClick: handleItemClick, tabIndex: -1, "data-non-pointer": inactive && !onClick, "data-inactive": inactive || undefined, "data-checked": (isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined, "data-variant": mode || undefined, "data-open": open || undefined, "aria-disabled": disabled || undefined, onKeyDown: handleItemKeyDown, onFocus: handleItemFocus, style: { '--level': level }, children: [!switchProp && isSelectionSingle && marker && !isParentNode && interactive && (_jsx("div", { className: styles.markerContainer, "data-test-id": 'list__base-item-marker' })), !switchProp && isSelectionMultiple && interactive && (_jsx("div", { className: styles.checkbox, children: _jsx(Checkbox, { size: CHECKBOX_SIZE_MAP[size !== null && size !== void 0 ? size : 's'], disabled: disabled, tabIndex: -1, onChange: handleCheckboxChange, checked: isChecked, "data-test-id": 'list__base-item-checkbox', onClick: handleCheckboxClick, indeterminate: indeterminate }) })), beforeContent && _jsx("div", { className: styles.beforeContent, children: beforeContent }), _jsxs("div", { className: styles.content, children: [_jsxs("div", { className: styles.headline, children: [_jsx("span", { className: styles.option, children: _jsx(TruncateString, { text: option, maxLines: 1 }) }), caption && _jsx("span", { className: styles.caption, children: caption })] }), description && (_jsx("div", { className: styles.description, children: _jsx(TruncateString, { text: description, maxLines: 2 }) }))] }), afterContent, switchProp && interactive && (_jsx(Switch, { disabled: disabled, checked: isChecked, "data-test-id": 'list__base-item-switch' })), !switchProp && expandIcon && _jsx("span", { className: styles.expandableIcon, children: expandIcon })] }));
72
72
  if (!itemWrapRender) {
73
73
  return item;
74
74
  }
@@ -173,13 +173,16 @@
173
173
  .droplistItem[data-non-pointer]{
174
174
  cursor:inherit;
175
175
  }
176
- .droplistItem:disabled .option,
176
+ .droplistItem[aria-disabled] .option,
177
+ .droplistItem[aria-disabled] .description,
178
+ .droplistItem[aria-disabled] .caption,
179
+ .droplistItem[aria-disabled] .expandableIcon, .droplistItem:disabled .option,
177
180
  .droplistItem:disabled .description,
178
181
  .droplistItem:disabled .caption,
179
182
  .droplistItem:disabled .expandableIcon{
180
183
  color:var(--sys-neutral-text-disabled, #9e9e9e);
181
184
  }
182
- .droplistItem:disabled .beforeContent{
185
+ .droplistItem[aria-disabled] .beforeContent, .droplistItem:disabled .beforeContent{
183
186
  opacity:var(--opacity-a064, 0.64);
184
187
  }
185
188
  .droplistItem[data-has-checked][data-variant=single]::after, .droplistItem[data-checked][data-variant=single]::after{
@@ -51,16 +51,16 @@ export function NextListItem(_a) {
51
51
  parentResetActiveFocusIndex === null || parentResetActiveFocusIndex === void 0 ? void 0 : parentResetActiveFocusIndex();
52
52
  return true;
53
53
  }, [parentResetActiveFocusIndex, parentResetNestedIndex]);
54
- return (_jsx("li", { style: { listStyleType: 'none' }, children: _jsx(Dropdown, { outsideClick: handleOutsideClick, fallbackPlacements: FALLBACK_PLACEMENTS, content: _jsx(ParentListContext.Provider, { value: {
55
- parentIds: ids,
56
- parentActiveFocusIndex: activeFocusIndex,
57
- parentExpandedIds: expandedIds,
58
- parentItemRefs: itemRefs,
59
- parentOpenNestedIndex: openNestedIndex,
60
- triggerRef,
61
- parentRef: listRef,
62
- parentResetNestedIndex: resetNestedIndex,
63
- parentResetActiveFocusIndex: resetActiveFocusIndex,
64
- toggleOpenCollapsedItems: id => setOpenCollapsedItems(items => items.includes(id) ? items.filter(item => item !== id) : items.concat([id])),
65
- }, children: _jsx(ListPrivate, { onKeyDown: handleListKeyDown, items: items, nested: true, search: search, scroll: scroll, scrollRef: scrollRef, limitedScrollHeight: true }) }), trigger: 'hover', open: (open || parentIds[parentOpenNestedIndex] === id) && !disabled, onOpenChange: handleOpenChange, placement: placement, children: _jsx(BaseItem, Object.assign({}, option, { disabled: disabled, open: open, expandIcon: _jsx(ChevronRightSVG, {}), id: id, isParentNode: true, indeterminate: isIndeterminate && !checked, onSelect: handleOnSelect })) }) }));
54
+ return (_jsx(Dropdown, { outsideClick: handleOutsideClick, fallbackPlacements: FALLBACK_PLACEMENTS, content: _jsx(ParentListContext.Provider, { value: {
55
+ parentIds: ids,
56
+ parentActiveFocusIndex: activeFocusIndex,
57
+ parentExpandedIds: expandedIds,
58
+ parentItemRefs: itemRefs,
59
+ parentOpenNestedIndex: openNestedIndex,
60
+ triggerRef,
61
+ parentRef: listRef,
62
+ parentResetNestedIndex: resetNestedIndex,
63
+ parentResetActiveFocusIndex: resetActiveFocusIndex,
64
+ toggleOpenCollapsedItems: id => setOpenCollapsedItems(items => items.includes(id) ? items.filter(item => item !== id) : items.concat([id])),
65
+ }, children: _jsx(ListPrivate, { onKeyDown: handleListKeyDown, items: items, nested: true, search: search, scroll: scroll, scrollRef: scrollRef, limitedScrollHeight: true }) }), trigger: 'hover', open: (open || parentIds[parentOpenNestedIndex] === id) && !disabled, onOpenChange: handleOpenChange, placement: placement, children: _jsx(BaseItem, Object.assign({}, option, { disabled: disabled, open: open, expandIcon: _jsx(ChevronRightSVG, {}), id: id, isParentNode: true, indeterminate: isIndeterminate && !checked, onSelect: handleOnSelect })) }));
66
66
  }
@@ -2,7 +2,7 @@ import { KeyboardEvent, RefObject } from 'react';
2
2
  type UseKeyboardNavigationProps = {
3
3
  ids: Array<number | string>;
4
4
  expandedIds: Array<number | string>;
5
- itemRefs?: RefObject<HTMLButtonElement>[];
5
+ itemRefs?: RefObject<HTMLElement>[];
6
6
  id?: string | number;
7
7
  };
8
8
  export declare function useKeyboardNavigation({ ids, expandedIds, itemRefs, id }: UseKeyboardNavigationProps): {
@@ -12,7 +12,7 @@ export declare function useKeyboardNavigation({ ids, expandedIds, itemRefs, id }
12
12
  setOpenNestedIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
13
13
  resetNestedIndex: () => void;
14
14
  resetActiveFocusIndex: () => void;
15
- handleListKeyDown: (e: KeyboardEvent<HTMLUListElement>) => void;
15
+ handleListKeyDown: (e: KeyboardEvent<HTMLElement>) => void;
16
16
  open: boolean;
17
17
  setOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
18
18
  };
@@ -25,18 +25,18 @@ export type BaseItemProps = WithSupportProps<{
25
25
  /** Основной контент айтема */
26
26
  content: ItemContentProps;
27
27
  /** Колбек обработки клика */
28
- onClick?(e: MouseEvent<HTMLButtonElement>): void;
28
+ onClick?(e: MouseEvent<HTMLElement>): void;
29
29
  /** Колбек обработки нажатия клавиши */
30
- onKeyDown?(e: KeyboardEvent<HTMLButtonElement>): void;
30
+ onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
31
31
  /** Колбек обработки фокуса */
32
- onFocus?(e: FocusEvent<HTMLButtonElement>): void;
32
+ onFocus?(e: FocusEvent<HTMLElement>): void;
33
33
  /** Колбек обработки блюра */
34
- onBlur?(e: FocusEvent<HTMLButtonElement>): void;
34
+ onBlur?(e: FocusEvent<HTMLElement>): void;
35
35
  /** Уникальный идентификатор */
36
36
  id?: string | number;
37
37
  /** Флаг неактивности элемента */
38
38
  disabled?: boolean;
39
- itemRef?: RefObject<HTMLButtonElement>;
39
+ itemRef?: RefObject<HTMLElement>;
40
40
  className?: string;
41
41
  /**
42
42
  * Флаг отображения отключения реакции на любое css состояние (hover/focus и тд)
@@ -5,7 +5,7 @@ export type ParentListContextType = {
5
5
  parentResetActiveFocusIndex?(): void;
6
6
  parentIds: Array<string | number>;
7
7
  parentExpandedIds: Array<string | number>;
8
- parentItemRefs: Array<RefObject<HTMLButtonElement>>;
8
+ parentItemRefs: Array<RefObject<HTMLElement>>;
9
9
  parentOpenNestedIndex: number;
10
10
  parentResetNestedIndex?(): void;
11
11
  openCollapsedItems?: Array<string | number>;
@@ -4,7 +4,7 @@ export type UseKeyboardNavigationProps<T extends HTMLElement> = {
4
4
  expandedIds: Array<number | string>;
5
5
  parentRef?: RefObject<T>;
6
6
  btnRef?: RefObject<HTMLButtonElement>;
7
- itemRefs?: RefObject<HTMLButtonElement>[];
7
+ itemRefs?: RefObject<HTMLElement>[];
8
8
  };
9
9
  export declare function useKeyboardNavigation<T extends HTMLElement>({ ids, itemRefs, expandedIds, parentRef, btnRef, }: UseKeyboardNavigationProps<T>): {
10
10
  activeFocusIndex: number;
package/dist/utils.d.ts CHANGED
@@ -6,11 +6,11 @@ type WithCollapsedItemsProps = {
6
6
  };
7
7
  export declare function withCollapsedItems({ items, openCollapsedItems }: WithCollapsedItemsProps): {
8
8
  items: ItemProps[];
9
- itemRefs: RefObject<HTMLButtonElement>[];
9
+ itemRefs: RefObject<HTMLElement>[];
10
10
  ids: (string | number)[];
11
11
  expandedIds: (string | number)[];
12
12
  };
13
- export declare function extractItemRefs(items: ItemProps[]): RefObject<HTMLButtonElement>[];
13
+ export declare function extractItemRefs(items: ItemProps[]): RefObject<HTMLElement>[];
14
14
  export declare function extractItemIds(items: ItemProps[]): Array<string | number>;
15
15
  export declare function extractChildIds({ items }: {
16
16
  items: ItemProps[];
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "List",
7
- "version": "0.2.2-preview-006b34c3.0",
7
+ "version": "0.3.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -45,5 +45,5 @@
45
45
  "merge-refs": "1.2.2",
46
46
  "uncontrollable": "8.0.4"
47
47
  },
48
- "gitHead": "8506192aa12bfb6f5359915a8601e942561d1b5a"
48
+ "gitHead": "88a44a8f4c6490f3004f7feac3d50d17ff03f31c"
49
49
  }
@@ -16,7 +16,7 @@ export function AccordionItem({ items: itemsProp, id, disabled, ...option }: Acc
16
16
 
17
17
  const { isChecked: open, handleClick: handleChange } = useToggleGroup({ value: String(id) });
18
18
 
19
- const handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {
19
+ const handleKeyDown = (e: KeyboardEvent<HTMLElement>) => {
20
20
  if (e.key === 'ArrowRight') {
21
21
  handleChange();
22
22
  toggleOpenCollapsedItems?.(id ?? '');
@@ -28,33 +28,31 @@ export function AccordionItem({ items: itemsProp, id, disabled, ...option }: Acc
28
28
 
29
29
  const itemsJSX = useRenderItems(itemsProp);
30
30
 
31
- const handleItemClick = (e: MouseEvent<HTMLButtonElement>) => {
31
+ const handleItemClick = (e: MouseEvent<HTMLElement>) => {
32
32
  handleChange();
33
33
  toggleOpenCollapsedItems?.(id ?? '');
34
34
  option.onClick?.(e);
35
35
  };
36
36
 
37
37
  return (
38
- <li style={{ listStyleType: 'none' }}>
39
- <CollapseBlockPrivate
40
- header={
41
- <BaseItem
42
- {...option}
43
- id={id}
44
- disabled={disabled}
45
- expandIcon={open ? <ChevronUpSVG /> : <ChevronDownSVG />}
46
- onClick={handleItemClick}
47
- isParentNode
48
- onKeyDown={handleKeyDown}
49
- indeterminate={isIndeterminate && !checked}
50
- onSelect={!disabled ? handleOnSelect : undefined}
51
- />
52
- }
53
- expanded={open}
54
- data-test-id={`list__accordion-item-${id}`}
55
- >
56
- <CollapseContext.Provider value={{ level: level + 1 }}>{itemsJSX}</CollapseContext.Provider>
57
- </CollapseBlockPrivate>
58
- </li>
38
+ <CollapseBlockPrivate
39
+ header={
40
+ <BaseItem
41
+ {...option}
42
+ id={id}
43
+ disabled={disabled}
44
+ expandIcon={open ? <ChevronUpSVG /> : <ChevronDownSVG />}
45
+ onClick={handleItemClick}
46
+ isParentNode
47
+ onKeyDown={handleKeyDown}
48
+ indeterminate={isIndeterminate && !checked}
49
+ onSelect={!disabled ? handleOnSelect : undefined}
50
+ />
51
+ }
52
+ expanded={open}
53
+ data-test-id={`list__accordion-item-${id}`}
54
+ >
55
+ <CollapseContext.Provider value={{ level: level + 1 }}>{itemsJSX}</CollapseContext.Provider>
56
+ </CollapseBlockPrivate>
59
57
  );
60
58
  }
@@ -1,5 +1,5 @@
1
1
  import cn from 'classnames';
2
- import { FocusEvent, KeyboardEvent, MouseEvent } from 'react';
2
+ import { FocusEvent, KeyboardEvent, MouseEvent, RefObject } from 'react';
3
3
 
4
4
  import { Checkbox, Switch } from '@snack-uikit/toggles';
5
5
  import { TruncateString } from '@snack-uikit/truncate-string';
@@ -49,7 +49,7 @@ export function BaseItem({
49
49
  onChange?.(id ?? '');
50
50
  };
51
51
 
52
- const handleItemClick = (e: MouseEvent<HTMLButtonElement>) => {
52
+ const handleItemClick = (e: MouseEvent<HTMLElement>) => {
53
53
  if (interactive) {
54
54
  parentResetActiveFocusIndex?.();
55
55
 
@@ -61,7 +61,7 @@ export function BaseItem({
61
61
  onClick?.(e);
62
62
  };
63
63
 
64
- const handleItemKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {
64
+ const handleItemKeyDown = (e: KeyboardEvent<HTMLElement>) => {
65
65
  onKeyDown?.(e);
66
66
 
67
67
  if (e.code === 'Space' || e.key === 'Enter') {
@@ -71,14 +71,14 @@ export function BaseItem({
71
71
 
72
72
  !isParentNode && handleChange();
73
73
  // TODO: should pass an event here?
74
- !isParentNode && onClick?.(e as unknown as MouseEvent<HTMLButtonElement>);
74
+ !isParentNode && onClick?.(e as unknown as MouseEvent<HTMLElement>);
75
75
 
76
76
  e.stopPropagation();
77
77
  e.preventDefault();
78
78
  }
79
79
  };
80
80
 
81
- const handleItemFocus = (e: FocusEvent<HTMLButtonElement>) => {
81
+ const handleItemFocus = (e: FocusEvent<HTMLElement>) => {
82
82
  onFocus?.(e);
83
83
  e.stopPropagation();
84
84
  };
@@ -98,65 +98,65 @@ export function BaseItem({
98
98
  const props = extractSupportProps(rest);
99
99
 
100
100
  const item = (
101
- <li role={'menuitem'} data-test-id={props['data-test-id'] || 'list__base-item_' + id}>
102
- <button
103
- ref={itemRef}
104
- className={cn(commonStyles.listItem, styles.droplistItem, className)}
105
- data-size={size}
106
- onClick={handleItemClick}
107
- tabIndex={-1}
108
- data-non-pointer={inactive && !onClick}
109
- data-inactive={inactive || undefined}
110
- data-checked={(isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined}
111
- data-variant={mode || undefined}
112
- data-open={open || undefined}
113
- disabled={disabled}
114
- onKeyDown={handleItemKeyDown}
115
- onFocus={handleItemFocus}
116
- style={{ '--level': level }}
117
- >
118
- {!switchProp && isSelectionSingle && marker && !isParentNode && interactive && (
119
- <div className={styles.markerContainer} data-test-id='list__base-item-marker' />
120
- )}
121
- {!switchProp && isSelectionMultiple && interactive && (
122
- <div className={styles.checkbox}>
123
- <Checkbox
124
- size={CHECKBOX_SIZE_MAP[size ?? 's']}
125
- disabled={disabled}
126
- tabIndex={-1}
127
- onChange={handleCheckboxChange}
128
- checked={isChecked}
129
- data-test-id='list__base-item-checkbox'
130
- onClick={handleCheckboxClick}
131
- indeterminate={indeterminate}
132
- />
133
- </div>
134
- )}
135
-
136
- {beforeContent && <div className={styles.beforeContent}>{beforeContent}</div>}
101
+ <li
102
+ role={'menuitem'}
103
+ data-test-id={props['data-test-id'] || 'list__base-item_' + id}
104
+ ref={itemRef as unknown as RefObject<HTMLLIElement>}
105
+ className={cn(commonStyles.listItem, styles.droplistItem, className)}
106
+ data-size={size}
107
+ onClick={handleItemClick}
108
+ tabIndex={-1}
109
+ data-non-pointer={inactive && !onClick}
110
+ data-inactive={inactive || undefined}
111
+ data-checked={(isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined}
112
+ data-variant={mode || undefined}
113
+ data-open={open || undefined}
114
+ aria-disabled={disabled || undefined}
115
+ onKeyDown={handleItemKeyDown}
116
+ onFocus={handleItemFocus}
117
+ style={{ '--level': level }}
118
+ >
119
+ {!switchProp && isSelectionSingle && marker && !isParentNode && interactive && (
120
+ <div className={styles.markerContainer} data-test-id='list__base-item-marker' />
121
+ )}
122
+ {!switchProp && isSelectionMultiple && interactive && (
123
+ <div className={styles.checkbox}>
124
+ <Checkbox
125
+ size={CHECKBOX_SIZE_MAP[size ?? 's']}
126
+ disabled={disabled}
127
+ tabIndex={-1}
128
+ onChange={handleCheckboxChange}
129
+ checked={isChecked}
130
+ data-test-id='list__base-item-checkbox'
131
+ onClick={handleCheckboxClick}
132
+ indeterminate={indeterminate}
133
+ />
134
+ </div>
135
+ )}
137
136
 
138
- <div className={styles.content}>
139
- <div className={styles.headline}>
140
- <span className={styles.option}>
141
- <TruncateString text={option} maxLines={1} />
142
- </span>
143
- {caption && <span className={styles.caption}>{caption}</span>}
144
- </div>
137
+ {beforeContent && <div className={styles.beforeContent}>{beforeContent}</div>}
145
138
 
146
- {description && (
147
- <div className={styles.description}>
148
- <TruncateString text={description} maxLines={2} />
149
- </div>
150
- )}
139
+ <div className={styles.content}>
140
+ <div className={styles.headline}>
141
+ <span className={styles.option}>
142
+ <TruncateString text={option} maxLines={1} />
143
+ </span>
144
+ {caption && <span className={styles.caption}>{caption}</span>}
151
145
  </div>
152
146
 
153
- {afterContent}
154
-
155
- {switchProp && interactive && (
156
- <Switch disabled={disabled} checked={isChecked} data-test-id='list__base-item-switch' />
147
+ {description && (
148
+ <div className={styles.description}>
149
+ <TruncateString text={description} maxLines={2} />
150
+ </div>
157
151
  )}
158
- {!switchProp && expandIcon && <span className={styles.expandableIcon}>{expandIcon}</span>}
159
- </button>
152
+ </div>
153
+
154
+ {afterContent}
155
+
156
+ {switchProp && interactive && (
157
+ <Switch disabled={disabled} checked={isChecked} data-test-id='list__base-item-switch' />
158
+ )}
159
+ {!switchProp && expandIcon && <span className={styles.expandableIcon}>{expandIcon}</span>}
160
160
  </li>
161
161
  );
162
162
 
@@ -138,6 +138,7 @@ $typography: (
138
138
  cursor: inherit;
139
139
  }
140
140
 
141
+ &[aria-disabled],
141
142
  &:disabled {
142
143
  .option,
143
144
  .description,
@@ -78,55 +78,53 @@ export function NextListItem({
78
78
  }, [parentResetActiveFocusIndex, parentResetNestedIndex]);
79
79
 
80
80
  return (
81
- <li style={{ listStyleType: 'none' }}>
82
- <Dropdown
83
- outsideClick={handleOutsideClick}
84
- fallbackPlacements={FALLBACK_PLACEMENTS}
85
- content={
86
- <ParentListContext.Provider
87
- value={{
88
- parentIds: ids,
89
- parentActiveFocusIndex: activeFocusIndex,
90
- parentExpandedIds: expandedIds,
91
- parentItemRefs: itemRefs,
92
- parentOpenNestedIndex: openNestedIndex,
93
- triggerRef,
94
- parentRef: listRef,
95
- parentResetNestedIndex: resetNestedIndex,
96
- parentResetActiveFocusIndex: resetActiveFocusIndex,
97
- toggleOpenCollapsedItems: id =>
98
- setOpenCollapsedItems(items =>
99
- items.includes(id) ? items.filter(item => item !== id) : items.concat([id]),
100
- ),
101
- }}
102
- >
103
- <ListPrivate
104
- onKeyDown={handleListKeyDown}
105
- items={items}
106
- nested
107
- search={search}
108
- scroll={scroll}
109
- scrollRef={scrollRef}
110
- limitedScrollHeight
111
- />
112
- </ParentListContext.Provider>
113
- }
114
- trigger='hover'
115
- open={(open || parentIds[parentOpenNestedIndex] === id) && !disabled}
116
- onOpenChange={handleOpenChange}
117
- placement={placement}
118
- >
119
- <BaseItem
120
- {...option}
121
- disabled={disabled}
122
- open={open}
123
- expandIcon={<ChevronRightSVG />}
124
- id={id}
125
- isParentNode
126
- indeterminate={isIndeterminate && !checked}
127
- onSelect={handleOnSelect}
128
- />
129
- </Dropdown>
130
- </li>
81
+ <Dropdown
82
+ outsideClick={handleOutsideClick}
83
+ fallbackPlacements={FALLBACK_PLACEMENTS}
84
+ content={
85
+ <ParentListContext.Provider
86
+ value={{
87
+ parentIds: ids,
88
+ parentActiveFocusIndex: activeFocusIndex,
89
+ parentExpandedIds: expandedIds,
90
+ parentItemRefs: itemRefs,
91
+ parentOpenNestedIndex: openNestedIndex,
92
+ triggerRef,
93
+ parentRef: listRef,
94
+ parentResetNestedIndex: resetNestedIndex,
95
+ parentResetActiveFocusIndex: resetActiveFocusIndex,
96
+ toggleOpenCollapsedItems: id =>
97
+ setOpenCollapsedItems(items =>
98
+ items.includes(id) ? items.filter(item => item !== id) : items.concat([id]),
99
+ ),
100
+ }}
101
+ >
102
+ <ListPrivate
103
+ onKeyDown={handleListKeyDown}
104
+ items={items}
105
+ nested
106
+ search={search}
107
+ scroll={scroll}
108
+ scrollRef={scrollRef}
109
+ limitedScrollHeight
110
+ />
111
+ </ParentListContext.Provider>
112
+ }
113
+ trigger='hover'
114
+ open={(open || parentIds[parentOpenNestedIndex] === id) && !disabled}
115
+ onOpenChange={handleOpenChange}
116
+ placement={placement}
117
+ >
118
+ <BaseItem
119
+ {...option}
120
+ disabled={disabled}
121
+ open={open}
122
+ expandIcon={<ChevronRightSVG />}
123
+ id={id}
124
+ isParentNode
125
+ indeterminate={isIndeterminate && !checked}
126
+ onSelect={handleOnSelect}
127
+ />
128
+ </Dropdown>
131
129
  );
132
130
  }
@@ -5,7 +5,7 @@ import { useParentListContext } from '../../Lists/contexts';
5
5
  type UseKeyboardNavigationProps = {
6
6
  ids: Array<number | string>;
7
7
  expandedIds: Array<number | string>;
8
- itemRefs?: RefObject<HTMLButtonElement>[];
8
+ itemRefs?: RefObject<HTMLElement>[];
9
9
  id?: string | number;
10
10
  };
11
11
 
@@ -17,7 +17,7 @@ export function useKeyboardNavigation({ ids, expandedIds, itemRefs, id }: UseKey
17
17
  const [openNestedIndex, setOpenNestedIndex] = useState<number>(-1);
18
18
  const [open, setOpen] = useState<boolean>(false);
19
19
 
20
- const handleListKeyDown = (e: KeyboardEvent<HTMLUListElement>) => {
20
+ const handleListKeyDown = (e: KeyboardEvent<HTMLElement>) => {
21
21
  switch (e.key) {
22
22
  case 'ArrowDown': {
23
23
  setActiveFocusIndex(activeIndex => Math.min(activeIndex + 1, ids.length - 1));
@@ -31,13 +31,13 @@ export type BaseItemProps = WithSupportProps<{
31
31
  content: ItemContentProps;
32
32
 
33
33
  /** Колбек обработки клика */
34
- onClick?(e: MouseEvent<HTMLButtonElement>): void;
34
+ onClick?(e: MouseEvent<HTMLElement>): void;
35
35
  /** Колбек обработки нажатия клавиши */
36
- onKeyDown?(e: KeyboardEvent<HTMLButtonElement>): void;
36
+ onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
37
37
  /** Колбек обработки фокуса */
38
- onFocus?(e: FocusEvent<HTMLButtonElement>): void;
38
+ onFocus?(e: FocusEvent<HTMLElement>): void;
39
39
  /** Колбек обработки блюра */
40
- onBlur?(e: FocusEvent<HTMLButtonElement>): void;
40
+ onBlur?(e: FocusEvent<HTMLElement>): void;
41
41
 
42
42
  /** Уникальный идентификатор */
43
43
  id?: string | number;
@@ -45,7 +45,7 @@ export type BaseItemProps = WithSupportProps<{
45
45
  /** Флаг неактивности элемента */
46
46
  disabled?: boolean;
47
47
 
48
- itemRef?: RefObject<HTMLButtonElement>;
48
+ itemRef?: RefObject<HTMLElement>;
49
49
  className?: string;
50
50
 
51
51
  /**
@@ -60,10 +60,10 @@ export function addItemsIds(itemsProp: ItemProps[], prefix?: string | number): I
60
60
  ...item,
61
61
  id: itemId,
62
62
  items: addItemsIds(item.items, itemId),
63
- itemRef: item.itemRef || createRef<HTMLButtonElement>(),
63
+ itemRef: item.itemRef || createRef<HTMLElement>(),
64
64
  };
65
65
  }
66
66
 
67
- return { ...item, id: itemId, itemRef: item.itemRef || createRef<HTMLButtonElement>() };
67
+ return { ...item, id: itemId, itemRef: item.itemRef || createRef<HTMLElement>() };
68
68
  });
69
69
  }
@@ -71,7 +71,7 @@ export const List = forwardRef<HTMLElement, ListProps>(
71
71
  [items, hasSearch, pinTop, pinBottom, footerRefs],
72
72
  );
73
73
 
74
- const listRef = useRef<HTMLUListElement>(null);
74
+ const listRef = useRef<HTMLElement>(null);
75
75
  const btnRef = useRef<HTMLButtonElement>(null);
76
76
 
77
77
  const { triggerRef } = useParentListContext();
@@ -93,7 +93,7 @@ export const List = forwardRef<HTMLElement, ListProps>(
93
93
 
94
94
  const isActive = listRef.current === document.activeElement && activeFocusIndex === -1 && openNestedIndex === -1;
95
95
 
96
- const mergedHandlerKeyDown = (e: KeyboardEvent<HTMLUListElement>) => {
96
+ const mergedHandlerKeyDown = (e: KeyboardEvent<HTMLElement>) => {
97
97
  onKeyDown?.(e);
98
98
  handleListKeyDown?.(e);
99
99
  };
@@ -7,7 +7,7 @@ export type ParentListContextType = {
7
7
 
8
8
  parentIds: Array<string | number>;
9
9
  parentExpandedIds: Array<string | number>;
10
- parentItemRefs: Array<RefObject<HTMLButtonElement>>;
10
+ parentItemRefs: Array<RefObject<HTMLElement>>;
11
11
 
12
12
  parentOpenNestedIndex: number;
13
13
  parentResetNestedIndex?(): void;
@@ -5,7 +5,7 @@ export type UseKeyboardNavigationProps<T extends HTMLElement> = {
5
5
  expandedIds: Array<number | string>;
6
6
  parentRef?: RefObject<T>;
7
7
  btnRef?: RefObject<HTMLButtonElement>;
8
- itemRefs?: RefObject<HTMLButtonElement>[];
8
+ itemRefs?: RefObject<HTMLElement>[];
9
9
  };
10
10
 
11
11
  export function useKeyboardNavigation<T extends HTMLElement>({
package/src/utils.ts CHANGED
@@ -14,7 +14,7 @@ type WithCollapsedItemsProps = {
14
14
  };
15
15
 
16
16
  export function withCollapsedItems({ items, openCollapsedItems }: WithCollapsedItemsProps) {
17
- let itemRefs: RefObject<HTMLButtonElement>[] = [];
17
+ let itemRefs: RefObject<HTMLElement>[] = [];
18
18
  let newItems: ItemProps[] = [];
19
19
  let ids: Array<string | number> = [];
20
20
  let expandedIds: Array<string | number> = [];
@@ -68,13 +68,13 @@ export function withCollapsedItems({ items, openCollapsedItems }: WithCollapsedI
68
68
  return { items, itemRefs, ids, expandedIds };
69
69
  }
70
70
 
71
- export function extractItemRefs(items: ItemProps[]): RefObject<HTMLButtonElement>[] {
72
- return items.reduce((prev: RefObject<HTMLButtonElement>[], item: ItemProps) => {
71
+ export function extractItemRefs(items: ItemProps[]): RefObject<HTMLElement>[] {
72
+ return items.reduce((prev: RefObject<HTMLElement>[], item: ItemProps) => {
73
73
  if (isGroupItemProps(item)) {
74
74
  return prev.concat(extractItemRefs(item.items));
75
75
  }
76
76
  return item.itemRef ? prev.concat([item.itemRef]) : prev;
77
- }, [] as RefObject<HTMLButtonElement>[]);
77
+ }, [] as RefObject<HTMLElement>[]);
78
78
  }
79
79
 
80
80
  export function extractItemIds(items: ItemProps[]): Array<string | number> {