@snack-uikit/list 0.19.0 → 0.21.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 +23 -0
- package/README.md +18 -2
- package/dist/cjs/components/Items/BaseItem/BaseItem.js +4 -2
- package/dist/cjs/components/Items/NextListItem/NextListItem.js +4 -3
- package/dist/cjs/components/Items/SearchItem/SearchItem.js +4 -2
- package/dist/cjs/components/Items/hooks.js +11 -9
- package/dist/cjs/components/Items/utils.js +5 -3
- package/dist/cjs/components/Lists/Droplist/DropList.js +12 -7
- package/dist/cjs/components/Lists/List/List.d.ts +7 -1
- package/dist/cjs/components/Lists/List/List.js +19 -11
- package/dist/cjs/components/Lists/ListPrivate/ListPrivate.d.ts +3 -2
- package/dist/cjs/components/Lists/ListPrivate/ListPrivate.js +17 -3
- package/dist/cjs/components/Lists/contexts/NewListProvider.d.ts +2 -4
- package/dist/cjs/components/Lists/contexts/NewListProvider.js +7 -3
- package/dist/cjs/components/Lists/hooks.d.ts +6 -1
- package/dist/cjs/components/Lists/hooks.js +32 -18
- package/dist/cjs/components/Lists/types.d.ts +12 -3
- package/dist/cjs/constants.d.ts +8 -0
- package/dist/cjs/constants.js +14 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/utils.d.ts +16 -0
- package/dist/cjs/utils.js +25 -0
- package/dist/esm/components/Items/BaseItem/BaseItem.js +3 -3
- package/dist/esm/components/Items/NextListItem/NextListItem.js +2 -1
- package/dist/esm/components/Items/SearchItem/SearchItem.js +3 -2
- package/dist/esm/components/Items/hooks.js +6 -4
- package/dist/esm/components/Items/utils.js +5 -3
- package/dist/esm/components/Lists/Droplist/DropList.js +20 -4
- package/dist/esm/components/Lists/List/List.d.ts +7 -1
- package/dist/esm/components/Lists/List/List.js +23 -6
- package/dist/esm/components/Lists/ListPrivate/ListPrivate.d.ts +3 -2
- package/dist/esm/components/Lists/ListPrivate/ListPrivate.js +12 -4
- package/dist/esm/components/Lists/contexts/NewListProvider.d.ts +2 -4
- package/dist/esm/components/Lists/contexts/NewListProvider.js +4 -2
- package/dist/esm/components/Lists/hooks.d.ts +6 -1
- package/dist/esm/components/Lists/hooks.js +29 -19
- package/dist/esm/components/Lists/types.d.ts +12 -3
- package/dist/esm/constants.d.ts +8 -0
- package/dist/esm/constants.js +8 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/utils.d.ts +16 -0
- package/dist/esm/utils.js +16 -0
- package/package.json +12 -12
- package/src/components/Items/BaseItem/BaseItem.tsx +4 -4
- package/src/components/Items/BaseItem/styles.module.scss +21 -21
- package/src/components/Items/NextListItem/NextListItem.tsx +2 -1
- package/src/components/Items/PinGroupItem/styles.module.scss +3 -4
- package/src/components/Items/SearchItem/SearchItem.tsx +3 -2
- package/src/components/Items/SearchItem/styles.module.scss +3 -3
- package/src/components/Items/hooks.tsx +6 -4
- package/src/components/Items/styles.module.scss +9 -9
- package/src/components/Items/utils.ts +5 -3
- package/src/components/Lists/Droplist/DropList.tsx +20 -3
- package/src/components/Lists/List/List.tsx +25 -5
- package/src/components/Lists/ListPrivate/ListPrivate.tsx +13 -3
- package/src/components/Lists/ListPrivate/styles.module.scss +11 -11
- package/src/components/Lists/contexts/NewListProvider.tsx +6 -2
- package/src/components/Lists/hooks.ts +35 -20
- package/src/components/Lists/styles.module.scss +8 -8
- package/src/components/Lists/types.ts +11 -3
- package/src/constants.ts +8 -0
- package/src/helperComponents/CollapseBlockPrivate/styles.module.scss +3 -3
- package/src/helperComponents/ItemContent/styles.module.scss +21 -22
- package/src/helperComponents/ListEmptyState/styles.module.scss +2 -2
- package/src/helperComponents/Separator/styles.module.scss +20 -22
- package/src/index.ts +3 -0
- package/src/utils.ts +20 -0
|
@@ -6,8 +6,8 @@ import { Scroll } from '@snack-uikit/scroll';
|
|
|
6
6
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
7
7
|
|
|
8
8
|
import { ListEmptyState, useEmptyState } from '../../../helperComponents';
|
|
9
|
-
import { PinBottomGroupItem, PinTopGroupItem, SearchItem, useRenderItems } from '../../Items';
|
|
10
|
-
import { useNewListContext } from '../contexts';
|
|
9
|
+
import { FlattenBaseItem, PinBottomGroupItem, PinTopGroupItem, SearchItem, useRenderItems } from '../../Items';
|
|
10
|
+
import { useNewListContext, useSelectionContext } from '../contexts';
|
|
11
11
|
import commonStyles from '../styles.module.scss';
|
|
12
12
|
import { ListPrivateProps } from '../types';
|
|
13
13
|
import styles from './styles.module.scss';
|
|
@@ -40,11 +40,14 @@ export const ListPrivate = forwardRef(
|
|
|
40
40
|
errorDataState,
|
|
41
41
|
dataError,
|
|
42
42
|
dataFiltered,
|
|
43
|
+
scrollToSelectedItem,
|
|
43
44
|
...props
|
|
44
45
|
}: ListPrivateProps,
|
|
45
46
|
ref: ForwardedRef<HTMLElement>,
|
|
46
47
|
) => {
|
|
47
|
-
const { size = 's' } = useNewListContext();
|
|
48
|
+
const { size = 's', flattenItems } = useNewListContext();
|
|
49
|
+
const { value, isSelectionSingle } = useSelectionContext();
|
|
50
|
+
const selectedItem = isSelectionSingle && value ? flattenItems[value] : undefined;
|
|
48
51
|
|
|
49
52
|
const itemsJSX = useRenderItems(items);
|
|
50
53
|
const itemsPinTopJSX = useRenderItems(pinTop);
|
|
@@ -88,6 +91,12 @@ export const ListPrivate = forwardRef(
|
|
|
88
91
|
[dataError, dataFiltered, emptyStates, hasNoItems, itemsJSX, loading, loadingJSX, search?.value],
|
|
89
92
|
);
|
|
90
93
|
|
|
94
|
+
const onScrollInitialized = () => {
|
|
95
|
+
if (scrollToSelectedItem) {
|
|
96
|
+
(selectedItem as FlattenBaseItem)?.itemRef?.current?.scrollIntoView();
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
91
100
|
const listJSX = (
|
|
92
101
|
<ul
|
|
93
102
|
className={cn(commonStyles.listContainer, className)}
|
|
@@ -120,6 +129,7 @@ export const ListPrivate = forwardRef(
|
|
|
120
129
|
ref={scrollContainerRef}
|
|
121
130
|
untouchableScrollbars={untouchableScrollbars}
|
|
122
131
|
onScroll={onScroll}
|
|
132
|
+
onInitialized={onScrollInitialized}
|
|
123
133
|
>
|
|
124
134
|
{content}
|
|
125
135
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
@
|
|
1
|
+
@use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
|
|
2
2
|
|
|
3
3
|
$sizes: 's', 'm', 'l';
|
|
4
4
|
|
|
5
5
|
$loader-height: (
|
|
6
|
-
's':
|
|
7
|
-
'm':
|
|
8
|
-
'l':
|
|
6
|
+
's': styles-tokens-element.$dimension-3m,
|
|
7
|
+
'm': styles-tokens-element.$dimension-4m,
|
|
8
|
+
'l': styles-tokens-element.$dimension-5m,
|
|
9
9
|
);
|
|
10
10
|
|
|
11
11
|
.loader {
|
|
@@ -15,10 +15,10 @@ $loader-height: (
|
|
|
15
15
|
|
|
16
16
|
@each $size in $sizes {
|
|
17
17
|
&[data-size='#{$size}'] {
|
|
18
|
-
height: simple-var($loader-height, $size);
|
|
18
|
+
height: styles-tokens-element.simple-var($loader-height, $size);
|
|
19
19
|
|
|
20
20
|
&[data-no-items] {
|
|
21
|
-
$no-items-loading-height: calc(3 * simple-var($loader-height, $size));
|
|
21
|
+
$no-items-loading-height: calc(3 * styles-tokens-element.simple-var($loader-height, $size));
|
|
22
22
|
|
|
23
23
|
min-width: calc(2 * $no-items-loading-height);
|
|
24
24
|
height: $no-items-loading-height;
|
|
@@ -27,15 +27,15 @@ $loader-height: (
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
&:focus-visible {
|
|
30
|
-
@include outline-inside-var(
|
|
30
|
+
@include styles-tokens-element.outline-inside-var(styles-tokens-element.$container-focused-s);
|
|
31
31
|
|
|
32
|
-
outline-color:
|
|
32
|
+
outline-color: styles-tokens-element.$sys-available-complementary;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
.scrollStub {
|
|
37
|
-
height: calc(
|
|
38
|
-
margin-top: calc(
|
|
37
|
+
height: calc(styles-tokens-element.$dimension-025m / 2);
|
|
38
|
+
margin-top: calc(styles-tokens-element.$dimension-025m / -2);
|
|
39
39
|
background: transparent;
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ $loader-height: (
|
|
|
43
43
|
display: flex;
|
|
44
44
|
flex-direction: column;
|
|
45
45
|
box-sizing: border-box;
|
|
46
|
-
padding:
|
|
46
|
+
padding: styles-tokens-element.$dimension-050m;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
.content {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createContext, ReactNode, useContext } from 'react';
|
|
2
2
|
|
|
3
|
+
import { ITEM_PREFIXES } from '../../../constants';
|
|
3
4
|
import { ItemContentProps } from '../../../helperComponents';
|
|
4
5
|
import { FlattenItem, FocusFlattenItem, ItemId } from '../../Items';
|
|
5
6
|
|
|
@@ -23,6 +24,7 @@ export type PublicListContextType = {
|
|
|
23
24
|
export type PrivateListContextType = {
|
|
24
25
|
flattenItems: Record<string, FlattenItem>;
|
|
25
26
|
focusFlattenItems: Record<string, FocusFlattenItem>;
|
|
27
|
+
firstItemId: ItemId;
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
type Child = {
|
|
@@ -31,9 +33,10 @@ type Child = {
|
|
|
31
33
|
|
|
32
34
|
type ListContextType = PublicListContextType & PrivateListContextType;
|
|
33
35
|
|
|
34
|
-
export const ListContext = createContext({
|
|
36
|
+
export const ListContext = createContext<ListContextType>({
|
|
35
37
|
flattenItems: {},
|
|
36
38
|
focusFlattenItems: {},
|
|
39
|
+
firstItemId: ITEM_PREFIXES.default,
|
|
37
40
|
});
|
|
38
41
|
|
|
39
42
|
export function useNewListContext() {
|
|
@@ -46,8 +49,9 @@ function extractListProps<T extends ListContextType>({
|
|
|
46
49
|
flattenItems,
|
|
47
50
|
focusFlattenItems,
|
|
48
51
|
contentRender,
|
|
52
|
+
firstItemId,
|
|
49
53
|
}: T) {
|
|
50
|
-
return { size, marker, contentRender, flattenItems, focusFlattenItems };
|
|
54
|
+
return { size, marker, contentRender, flattenItems, focusFlattenItems, firstItemId };
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
export function NewListContextProvider({ children, ...props }: ListContextType & Child) {
|
|
@@ -1,21 +1,33 @@
|
|
|
1
|
-
import { KeyboardEvent, RefObject, useCallback, useRef, useState } from 'react';
|
|
1
|
+
import { KeyboardEvent, RefObject, useCallback, useImperativeHandle, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
|
+
import { ITEM_PREFIXES } from '../../constants';
|
|
3
4
|
import { FocusFlattenItem, ItemId } from '../Items';
|
|
4
5
|
|
|
5
6
|
type UseNewKeyboardNavigationProps<T extends HTMLElement> = {
|
|
6
7
|
mainRef?: RefObject<T>;
|
|
7
8
|
btnRef?: RefObject<HTMLButtonElement>;
|
|
8
9
|
focusFlattenItems: Record<string, FocusFlattenItem>;
|
|
10
|
+
keyboardNavigationRef?: RefObject<{ focusItem(item: ItemId): void }>;
|
|
11
|
+
hasListInFocusChain: boolean;
|
|
12
|
+
firstItemId: ItemId;
|
|
9
13
|
};
|
|
10
14
|
|
|
11
15
|
export function useNewKeyboardNavigation<T extends HTMLElement>({
|
|
12
16
|
mainRef,
|
|
13
17
|
btnRef,
|
|
14
18
|
focusFlattenItems,
|
|
19
|
+
keyboardNavigationRef,
|
|
20
|
+
hasListInFocusChain,
|
|
21
|
+
firstItemId,
|
|
15
22
|
}: UseNewKeyboardNavigationProps<T>) {
|
|
16
|
-
const
|
|
23
|
+
const defaultActiveItemId = hasListInFocusChain ? undefined : firstItemId;
|
|
24
|
+
const [activeItemId, setActiveItemId] = useState<ItemId | undefined>(() => defaultActiveItemId);
|
|
25
|
+
const activeItemIdRef = useRef<ItemId | undefined>(defaultActiveItemId);
|
|
17
26
|
|
|
18
|
-
const
|
|
27
|
+
const resetActiveItemId = useCallback(() => {
|
|
28
|
+
setActiveItemId(defaultActiveItemId);
|
|
29
|
+
activeItemIdRef.current = defaultActiveItemId;
|
|
30
|
+
}, [defaultActiveItemId]);
|
|
19
31
|
|
|
20
32
|
const handleListKeyDownFactory = useCallback(
|
|
21
33
|
(ids: ItemId[], expandedIds: ItemId[]) => (e: KeyboardEvent<T>) => {
|
|
@@ -52,12 +64,14 @@ export function useNewKeyboardNavigation<T extends HTMLElement>({
|
|
|
52
64
|
}
|
|
53
65
|
case 'ArrowUp': {
|
|
54
66
|
if (ids[0] === activeItemIdRef.current) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
if (hasListInFocusChain) {
|
|
68
|
+
const item = focusFlattenItems[ids[0]];
|
|
69
|
+
|
|
70
|
+
if (item.parentId === ITEM_PREFIXES.default) {
|
|
71
|
+
activeItemIdRef.current = undefined;
|
|
72
|
+
setActiveItemId(undefined);
|
|
73
|
+
mainRef?.current?.focus();
|
|
74
|
+
}
|
|
61
75
|
}
|
|
62
76
|
} else if (activeItemIdRef.current !== undefined) {
|
|
63
77
|
const activeIndex = ids.findIndex(id => id === activeItemIdRef.current);
|
|
@@ -99,12 +113,16 @@ export function useNewKeyboardNavigation<T extends HTMLElement>({
|
|
|
99
113
|
|
|
100
114
|
case 'Tab': {
|
|
101
115
|
if (activeItemIdRef.current !== undefined) {
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
if (hasListInFocusChain) {
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
e.stopPropagation();
|
|
104
119
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
120
|
+
activeItemIdRef.current = undefined;
|
|
121
|
+
setActiveItemId(undefined);
|
|
122
|
+
mainRef?.current?.focus();
|
|
123
|
+
} else {
|
|
124
|
+
resetActiveItemId();
|
|
125
|
+
}
|
|
108
126
|
} else {
|
|
109
127
|
btnRef && !e.shiftKey ? btnRef?.current?.focus() : mainRef?.current?.focus();
|
|
110
128
|
}
|
|
@@ -116,14 +134,9 @@ export function useNewKeyboardNavigation<T extends HTMLElement>({
|
|
|
116
134
|
}
|
|
117
135
|
}
|
|
118
136
|
},
|
|
119
|
-
[focusFlattenItems, mainRef, btnRef],
|
|
137
|
+
[focusFlattenItems, hasListInFocusChain, mainRef, resetActiveItemId, btnRef],
|
|
120
138
|
);
|
|
121
139
|
|
|
122
|
-
const resetActiveItemId = useCallback(() => {
|
|
123
|
-
setActiveItemId(undefined);
|
|
124
|
-
activeItemIdRef.current = undefined;
|
|
125
|
-
}, []);
|
|
126
|
-
|
|
127
140
|
const forceUpdateActiveItemId = useCallback(
|
|
128
141
|
(itemId: ItemId) => {
|
|
129
142
|
setActiveItemId(itemId);
|
|
@@ -136,6 +149,8 @@ export function useNewKeyboardNavigation<T extends HTMLElement>({
|
|
|
136
149
|
[focusFlattenItems],
|
|
137
150
|
);
|
|
138
151
|
|
|
152
|
+
useImperativeHandle(keyboardNavigationRef, () => ({ focusItem: forceUpdateActiveItemId }), [forceUpdateActiveItemId]);
|
|
153
|
+
|
|
139
154
|
return {
|
|
140
155
|
resetActiveItemId,
|
|
141
156
|
activeItemId,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@
|
|
1
|
+
@use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
|
|
2
2
|
|
|
3
3
|
.listContainer {
|
|
4
4
|
display: flex;
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
outline: none;
|
|
14
14
|
|
|
15
15
|
&[data-active] {
|
|
16
|
-
@include outline-inside-var(
|
|
16
|
+
@include styles-tokens-element.outline-inside-var(styles-tokens-element.$container-focused-s);
|
|
17
17
|
|
|
18
|
-
outline-color:
|
|
18
|
+
outline-color: styles-tokens-element.$sys-available-complementary;
|
|
19
19
|
|
|
20
20
|
* {
|
|
21
21
|
cursor: inherit;
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
height: 100%;
|
|
40
40
|
|
|
41
41
|
&:has(.listContainer:focus-visible) {
|
|
42
|
-
@include outline-inside-var(
|
|
42
|
+
@include styles-tokens-element.outline-inside-var(styles-tokens-element.$container-focused-s);
|
|
43
43
|
|
|
44
|
-
outline-color:
|
|
44
|
+
outline-color: styles-tokens-element.$sys-available-complementary;
|
|
45
45
|
}
|
|
46
46
|
li,
|
|
47
47
|
ul {
|
|
@@ -51,15 +51,15 @@
|
|
|
51
51
|
|
|
52
52
|
.scrollContainerS {
|
|
53
53
|
height: auto;
|
|
54
|
-
max-height: calc(
|
|
54
|
+
max-height: calc(styles-tokens-element.$dimension-1m * 32); // 256px
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.scrollContainerM {
|
|
58
58
|
height: auto;
|
|
59
|
-
max-height: calc(
|
|
59
|
+
max-height: calc(styles-tokens-element.$dimension-1m * 40); // 320px
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
.scrollContainerL {
|
|
63
63
|
height: auto;
|
|
64
|
-
max-height: calc(
|
|
64
|
+
max-height: calc(styles-tokens-element.$dimension-1m * 48); // 384px
|
|
65
65
|
}
|
|
@@ -34,6 +34,8 @@ export type ListProps = WithSupportProps<
|
|
|
34
34
|
footer?: ReactNode;
|
|
35
35
|
/** Список ссылок на кастомные элементы, помещенные в специальную секцию внизу списка */
|
|
36
36
|
footerActiveElementsRefs?: RefObject<HTMLElement>[];
|
|
37
|
+
/** Ссылка на управление навигацией листа с клавиатуры */
|
|
38
|
+
keyboardNavigationRef?: RefObject<{ focusItem(id: ItemId): void }>;
|
|
37
39
|
/** Настройки поисковой строки */
|
|
38
40
|
search?: SearchState;
|
|
39
41
|
|
|
@@ -43,10 +45,16 @@ export type ListProps = WithSupportProps<
|
|
|
43
45
|
collapse?: CollapseState;
|
|
44
46
|
/** CSS-класс */
|
|
45
47
|
className?: string;
|
|
46
|
-
onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
|
|
47
48
|
|
|
48
49
|
/** Флаг, отвещающий за состояние загрузки списка */
|
|
49
50
|
loading?: boolean;
|
|
51
|
+
|
|
52
|
+
/** Обработчик события по нажатию клавиш */
|
|
53
|
+
onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
|
|
54
|
+
/** Флаг, отвещающий за включение самого родительского контейнера листа в цепочку фокусирующихся элементов */
|
|
55
|
+
hasListInFocusChain?: boolean;
|
|
56
|
+
/** Флаг, отвещающий за прокручивание до выбранного элемента */
|
|
57
|
+
scrollToSelectedItem?: boolean;
|
|
50
58
|
} & SelectionState &
|
|
51
59
|
PublicListContextType &
|
|
52
60
|
ScrollProps &
|
|
@@ -74,9 +82,9 @@ export type DroplistProps = {
|
|
|
74
82
|
*/
|
|
75
83
|
children: ReactNode | ((params: { onKeyDown?: (e: KeyboardEvent<HTMLElement>) => void }) => ReactNode);
|
|
76
84
|
} & Pick<DropdownProps, 'trigger' | 'placement' | 'widthStrategy' | 'open' | 'onOpenChange' | 'triggerClassName'> &
|
|
77
|
-
Omit<ListProps, 'tabIndex' | 'onKeyDown'>;
|
|
85
|
+
Omit<ListProps, 'tabIndex' | 'onKeyDown' | 'hasListInFocusChain' | 'keyboardNavigationRef'>;
|
|
78
86
|
|
|
79
|
-
export type ListPrivateProps = Omit<ListProps, 'pinTop' | 'pinBottom' | 'items'> & {
|
|
87
|
+
export type ListPrivateProps = Omit<ListProps, 'pinTop' | 'pinBottom' | 'items' | 'hasListInFocusChain'> & {
|
|
80
88
|
nested?: boolean;
|
|
81
89
|
active?: boolean;
|
|
82
90
|
tabIndex?: number;
|
package/src/constants.ts
ADDED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@
|
|
1
|
+
@use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
|
|
2
2
|
|
|
3
3
|
$duration: 300ms;
|
|
4
4
|
|
|
@@ -45,7 +45,7 @@ $duration: 300ms;
|
|
|
45
45
|
width: 100%;
|
|
46
46
|
height: 100%;
|
|
47
47
|
|
|
48
|
-
opacity:
|
|
49
|
-
background-color:
|
|
48
|
+
opacity: styles-tokens-element.$opacity-a004;
|
|
49
|
+
background-color: styles-tokens-element.$sys-neutral-accent-default;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
@
|
|
2
|
-
@import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
|
|
1
|
+
@use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-dropList';
|
|
3
2
|
|
|
4
3
|
$sizes: 's', 'm', 'l';
|
|
5
4
|
$typography: (
|
|
6
5
|
's': (
|
|
7
|
-
'label':
|
|
8
|
-
'caption':
|
|
9
|
-
'description':
|
|
10
|
-
'separator':
|
|
6
|
+
'label': styles-tokens-dropList.$sans-body-s,
|
|
7
|
+
'caption': styles-tokens-dropList.$sans-body-s,
|
|
8
|
+
'description': styles-tokens-dropList.$sans-body-s,
|
|
9
|
+
'separator': styles-tokens-dropList.$light-label-m,
|
|
11
10
|
),
|
|
12
11
|
'm': (
|
|
13
|
-
'label':
|
|
14
|
-
'caption':
|
|
15
|
-
'description':
|
|
16
|
-
'separator':
|
|
12
|
+
'label': styles-tokens-dropList.$sans-body-m,
|
|
13
|
+
'caption': styles-tokens-dropList.$sans-body-s,
|
|
14
|
+
'description': styles-tokens-dropList.$sans-body-s,
|
|
15
|
+
'separator': styles-tokens-dropList.$light-label-l,
|
|
17
16
|
),
|
|
18
17
|
'l': (
|
|
19
|
-
'label':
|
|
20
|
-
'caption':
|
|
21
|
-
'description':
|
|
22
|
-
'separator':
|
|
18
|
+
'label': styles-tokens-dropList.$sans-body-l,
|
|
19
|
+
'caption': styles-tokens-dropList.$sans-body-m,
|
|
20
|
+
'description': styles-tokens-dropList.$sans-body-m,
|
|
21
|
+
'separator': styles-tokens-dropList.$light-label-l,
|
|
23
22
|
),
|
|
24
23
|
);
|
|
25
24
|
|
|
@@ -30,18 +29,18 @@ $typography: (
|
|
|
30
29
|
.label {
|
|
31
30
|
overflow: hidden;
|
|
32
31
|
flex: 1;
|
|
33
|
-
color:
|
|
32
|
+
color: styles-tokens-dropList.$sys-neutral-text-main;
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
.caption {
|
|
37
36
|
overflow: hidden;
|
|
38
|
-
color:
|
|
37
|
+
color: styles-tokens-dropList.$sys-neutral-text-light;
|
|
39
38
|
text-overflow: ellipsis;
|
|
40
39
|
white-space: nowrap;
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
.description {
|
|
44
|
-
color:
|
|
43
|
+
color: styles-tokens-dropList.$sys-neutral-text-support;
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
.content {
|
|
@@ -53,19 +52,19 @@ $typography: (
|
|
|
53
52
|
@each $size in $sizes {
|
|
54
53
|
&[data-size='#{$size}'] {
|
|
55
54
|
.headline {
|
|
56
|
-
@include composite-var(
|
|
55
|
+
@include styles-tokens-dropList.composite-var(styles-tokens-dropList.$drop-list, 'item', $size, 'headline');
|
|
57
56
|
}
|
|
58
57
|
.label {
|
|
59
|
-
@include composite-var($typography, $size, 'label');
|
|
58
|
+
@include styles-tokens-dropList.composite-var($typography, $size, 'label');
|
|
60
59
|
|
|
61
60
|
display: flex;
|
|
62
61
|
align-items: center;
|
|
63
62
|
}
|
|
64
63
|
.caption {
|
|
65
|
-
@include composite-var($typography, $size, 'caption');
|
|
64
|
+
@include styles-tokens-dropList.composite-var($typography, $size, 'caption');
|
|
66
65
|
}
|
|
67
66
|
.description {
|
|
68
|
-
@include composite-var($typography, $size, 'description');
|
|
67
|
+
@include styles-tokens-dropList.composite-var($typography, $size, 'description');
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
}
|
|
@@ -74,7 +73,7 @@ $typography: (
|
|
|
74
73
|
.label,
|
|
75
74
|
.description,
|
|
76
75
|
.caption {
|
|
77
|
-
color:
|
|
76
|
+
color: styles-tokens-dropList.$sys-neutral-text-disabled;
|
|
78
77
|
}
|
|
79
78
|
}
|
|
80
79
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@
|
|
1
|
+
@use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
|
|
2
2
|
|
|
3
3
|
.listEmptyStateWrapper {
|
|
4
4
|
display: flex;
|
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
justify-content: center;
|
|
8
8
|
|
|
9
9
|
box-sizing: border-box;
|
|
10
|
-
padding:
|
|
10
|
+
padding: styles-tokens-element.$dimension-1m;
|
|
11
11
|
}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
@
|
|
2
|
-
@
|
|
3
|
-
@import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
|
|
1
|
+
@use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-button-buttonFunction';
|
|
2
|
+
@use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-dropList';
|
|
4
3
|
|
|
5
4
|
$sizes: 's', 'm', 'l';
|
|
6
5
|
|
|
7
6
|
$typography-primary: (
|
|
8
|
-
's':
|
|
9
|
-
'm':
|
|
10
|
-
'l':
|
|
7
|
+
's': styles-tokens-button-buttonFunction.$sans-label-m,
|
|
8
|
+
'm': styles-tokens-button-buttonFunction.$sans-label-l,
|
|
9
|
+
'l': styles-tokens-button-buttonFunction.$sans-title-m,
|
|
11
10
|
);
|
|
12
11
|
|
|
13
12
|
$typography-secondary: (
|
|
14
|
-
's':
|
|
15
|
-
'm':
|
|
16
|
-
'l':
|
|
13
|
+
's': styles-tokens-button-buttonFunction.$light-label-m,
|
|
14
|
+
'm': styles-tokens-button-buttonFunction.$light-label-l,
|
|
15
|
+
'l': styles-tokens-button-buttonFunction.$light-title-m,
|
|
17
16
|
);
|
|
18
17
|
|
|
19
18
|
$button-size: (
|
|
@@ -26,7 +25,7 @@ $containerSize: 1px;
|
|
|
26
25
|
|
|
27
26
|
.separatorWithLabel {
|
|
28
27
|
display: flex;
|
|
29
|
-
gap:
|
|
28
|
+
gap: styles-tokens-button-buttonFunction.$dimension-1m;
|
|
30
29
|
align-items: flex-end;
|
|
31
30
|
|
|
32
31
|
box-sizing: border-box;
|
|
@@ -35,14 +34,14 @@ $containerSize: 1px;
|
|
|
35
34
|
|
|
36
35
|
@each $size in $sizes {
|
|
37
36
|
&[data-size='#{$size}'] {
|
|
38
|
-
@include composite-var(
|
|
37
|
+
@include styles-tokens-button-buttonFunction.composite-var(styles-tokens-dropList.$drop-list, 'item', $size, 'container-separator-subheader');
|
|
39
38
|
|
|
40
39
|
.label {
|
|
41
40
|
&[data-mode='primary'] {
|
|
42
|
-
@include composite-var(simple-var($typography-primary, $size));
|
|
41
|
+
@include styles-tokens-button-buttonFunction.composite-var(styles-tokens-button-buttonFunction.simple-var($typography-primary, $size));
|
|
43
42
|
}
|
|
44
43
|
&[data-mode='secondary'] {
|
|
45
|
-
@include composite-var(simple-var($typography-secondary, $size));
|
|
44
|
+
@include styles-tokens-button-buttonFunction.composite-var(styles-tokens-button-buttonFunction.simple-var($typography-secondary, $size));
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
}
|
|
@@ -55,7 +54,7 @@ $containerSize: 1px;
|
|
|
55
54
|
|
|
56
55
|
@each $size in $sizes {
|
|
57
56
|
&[data-size='#{$size}'] {
|
|
58
|
-
@include composite-var(
|
|
57
|
+
@include styles-tokens-button-buttonFunction.composite-var(styles-tokens-dropList.$drop-list, 'item', $size, 'container-separator');
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
60
|
|
|
@@ -67,11 +66,11 @@ $containerSize: 1px;
|
|
|
67
66
|
flex-shrink: 1;
|
|
68
67
|
|
|
69
68
|
&[data-mode='primary'] {
|
|
70
|
-
color:
|
|
69
|
+
color: styles-tokens-button-buttonFunction.$sys-neutral-text-main;
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
&[data-mode='secondary'] {
|
|
74
|
-
color:
|
|
73
|
+
color: styles-tokens-button-buttonFunction.$sys-neutral-text-light;
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -98,15 +97,14 @@ hr.divider {
|
|
|
98
97
|
transform: translateY(
|
|
99
98
|
calc(
|
|
100
99
|
(
|
|
101
|
-
simple-var(
|
|
102
|
-
|
|
100
|
+
styles-tokens-button-buttonFunction.simple-var(
|
|
101
|
+
styles-tokens-button-buttonFunction.$button-function,
|
|
103
102
|
'container',
|
|
104
|
-
simple-var($button-size, $size),
|
|
103
|
+
styles-tokens-button-buttonFunction.simple-var($button-size, $size),
|
|
105
104
|
'label-only',
|
|
106
105
|
'height'
|
|
107
|
-
) - simple-var(
|
|
108
|
-
) /
|
|
109
|
-
2 - var(--divider-height, 0)
|
|
106
|
+
) - styles-tokens-button-buttonFunction.simple-var(styles-tokens-button-buttonFunction.$theme-variables, 'sans', 'label', $size, 'line-height')
|
|
107
|
+
) / 2 - var(--divider-height, 0)
|
|
110
108
|
)
|
|
111
109
|
);
|
|
112
110
|
}
|
package/src/index.ts
CHANGED
package/src/utils.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ItemId } from './components';
|
|
2
|
+
import { ITEM_PREFIXES } from './constants';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Возвращает id для элемента футера
|
|
6
|
+
* @function helper
|
|
7
|
+
*/
|
|
8
|
+
export const getFooterItemId = (id: ItemId) => `${ITEM_PREFIXES.footer}__${id}`;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Возвращает id для элемента, подставляя перфикс
|
|
12
|
+
* @function helper
|
|
13
|
+
*/
|
|
14
|
+
export const getItemAutoId = (prefix: ItemId, id: ItemId) => [prefix, id].join('-');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Возвращает id для дефолтного элемента
|
|
18
|
+
* @function helper
|
|
19
|
+
*/
|
|
20
|
+
export const getDefaultItemId = (id: ItemId) => getItemAutoId(ITEM_PREFIXES.default, id);
|