Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
gizeasy committed Oct 4, 2023
2 parents 1e839b5 + b1c5bf7 commit 94a0b0e
Show file tree
Hide file tree
Showing 46 changed files with 944 additions and 266 deletions.
29 changes: 19 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## v4.31.0 (04/10/2023)
Самое важное:
- в `ContextMenu` добавили управление с клавиатуры
- переписали HOC `withTooltip` и добавили в него анимацию появления тултипа
- теперь можно отдельно импортировать изображения `Responses`
- добавили миксин `MixFlex`
- добавили в документацию компонента `Slider` описание свойства `onAfterChange`

---

- [feat(ContextMenu): add keyboard navigation (#3259)](https://github.com/consta-design-system/uikit/commit/477c710d274375bae9263d75ad117006ce2b4b53) - [@N1MBER](https://github.com/N1MBER)
- [fix(List): fixed default color of list items in dark theme (#3324)](https://github.com/consta-design-system/uikit/commit/81308b2b9f55f8ba865ca5b12134ee3493c0486f) - [@levi2ki](https://github.com/levi2ki)
- [docs(Slider): added description of the onAfterChange property (#3327)](https://github.com/consta-design-system/uikit/commit/c9d3da82acf675f98912d72411ccb1410e37e1cc) - [@N1MBER](https://github.com/N1MBER)
- [feat(withTooltip): add animate and refactor HOC (#3310)](https://github.com/consta-design-system/uikit/commit/c7dd62e56feb41c18e4a2bf0d11de76afb419dc2) - [@gizeasy](https://github.com/gizeasy)
- [feat(Responses): added images reexports (#3308)](https://github.com/consta-design-system/uikit/commit/04c832e480d19a08e6c81ad72e3a71eff7bf9a33) - [@gizeasy](https://github.com/gizeasy)
- [feat(MixFlex): add new mixin (#3294)](https://github.com/consta-design-system/uikit/commit/fda9e848c80ad2ab22ed7da89868bb0499eb2ae5) - [@N1MBER](https://github.com/N1MBER)

--------------------

## v4.30.1 (27/09/2023)
- [fix(List): fixed background on ListItem (#3300)](https://github.com/consta-design-system/uikit/commit/6b87a1e491836354e17626440e8adcd14f2b414f) - [@gizeasy](https://github.com/gizeasy)
- [fix(Selects): fix render numbers value (#3297)](https://github.com/consta-design-system/uikit/commit/f129a3482476c59038252295f9a5853c203b12b2) - [@N1MBER](https://github.com/N1MBER)
Expand Down Expand Up @@ -400,13 +419,3 @@
- [fix(Table): fix bug with excluding in calculations previous state (#2877)](https://github.com/consta-design-system/uikit/commit/685024043045074fe01af43a4835801a390b1f98) - [@N1MBER](https://github.com/N1MBER)
- [docs(sandbox): add links to sandbox for a few components and hooks (#2876)](https://github.com/consta-design-system/uikit/commit/d3f9450afb472c6a24963b07000cab6619305ab3) - [@N1MBER](https://github.com/N1MBER)
- [chore(deps): update @consta/stand](https://github.com/consta-design-system/uikit/commit/9cd4a1569a6975eb83c502705647fc246ca53499) - [@gizeasy](https://github.com/gizeasy)

--------------------

## v4.8.0 (31/01/2023)
Самое важное:
- Добавили мобильный вид в `ContextMenu` и переработали анимацию раскрытия вложенных меню.
---

- [feat(ContextMenu): mobile view added (#2872)](https://github.com/consta-design-system/uikit/commit/a46494848d343ed2020bc61cdd37e33ef23394e9) - [@gizeasy](https://github.com/gizeasy)
- [chore(deps): update @consta/icons and @consta/stand](https://github.com/consta-design-system/uikit/commit/3e08155f0dbf660418afce22a179cd8525231c27) - [@gizeasy](https://github.com/gizeasy)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@consta/uikit",
"version": "4.30.1",
"version": "4.31.0",
"keywords": [
"ui-kit",
"design-system",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
}
}

.ContextMenuLevel {
&-Item:not(.ContextMenuLevel-Item_active):not(:focus) {
&.ListItem_interactive:hover {
background: transparent;
}
}
}

.ContextMenuLevel-Mobile {
position: absolute;
top: 0;
Expand Down
217 changes: 147 additions & 70 deletions src/components/ContextMenu/ContextMenuLevel/ContextMenuLevel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ import './ContextMenuLevel.css';

import { IconArrowLeft } from '@consta/icons/IconArrowLeft';
import { IconArrowRight } from '@consta/icons/IconArrowRight';
import React, { forwardRef, useEffect } from 'react';
import React, { forwardRef, useEffect, useMemo } from 'react';

import {
cnListBox,
List,
ListDivider,
ListItem,
ListPropOnItemClick,
mapIconSize,
mapVerticalSpase,
} from '##/components/ListCanary';
import { useFlag } from '##/hooks/useFlag/useFlag';
import { useRefs } from '##/hooks/useRefs/useRefs';
import { useForkRef } from '##/hooks/useForkRef';
import { cnMixPopoverAnimate } from '##/mixs/MixPopoverAnimate';
import { cnMixSpace } from '##/mixs/MixSpace';
import { cn } from '##/utils/bem';
Expand All @@ -26,6 +27,7 @@ import {
ContextMenuLevelComponent,
ContextMenuLevelProps,
} from '../types';
import { useMenuNavigation } from '../useMenuNavigation';

export const cnContextMenuLevel = cn('ContextMenuLevel');

Expand All @@ -52,13 +54,15 @@ const ContextMenuLevelRender = (
animate,
// Свойства относящиеся к меню
levelDepth,
activeLevelDepth,
activeItem,
addLevel,
deleteLevel,
setHoveredParenLevel,
hoveredParenLevel,
sortGroup,
onItemClick,
onItemClick: onItemClickProp,
onEsc,
isOpen,
parent,
isMobile,
Expand All @@ -72,15 +76,15 @@ const ContextMenuLevelRender = (
anchorRef,
// Геттеры для ITEM
getItemLabel,
getItemRightSide,
getItemRightSide: getItemRightSideProp,
getItemLeftSide,
getItemSubMenu,
getItemStatus,
getItemDisabled,
getItemKey,
getItemOnClick,
getItemOnClick: getItemOnClickProp,
getItemAs,
getItemAttributes,
getItemAttributes: getItemAttributesProp,
getItemGroupId,
getItemLeftIcon,
getItemRightIcon,
Expand All @@ -90,33 +94,13 @@ const ContextMenuLevelRender = (
...otherProps
} = props;

const firstLevel = levelDepth === 0;

const [hovered, setHovered] = useFlag(false);

const getKey = (item: ContextMenuItemDefault) =>
(getItemKey(item) || getItemLabel(item)).toString();

const itemsRefs = useRefs<HTMLDivElement, string[]>(
items.map((item) => getKey(item)),
[groupsProp],
);

useEffect(() => {
if (levelDepth !== 0 && !hovered && hoveredParenLevel < levelDepth) {
clearTimeout(timers[levelDepth]);
timers[levelDepth] = setTimeout(
() => deleteLevel(levelDepth),
closeDelay,
);
}
return () => clearTimeout(timers[levelDepth]);
}, [hovered, hoveredParenLevel]);

useEffect(() => {
if (!isOpen) {
clearTimeout(timers[levelDepth]);
}
}, [isOpen]);

const addCurrentLevel = (item: ContextMenuItemDefault) => {
const subMenu = getItemSubMenu(item);
const disabled = getItemDisabled(item);
Expand All @@ -136,18 +120,126 @@ const ContextMenuLevelRender = (
}
};

const handleEscClick: React.KeyboardEventHandler = (e) => {
onEsc?.(e);
anchorRef?.current?.focus();
};

const {
refs,
onKeyDown,
activeIndex,
setActiveIndex,
setDirection,
parentRef,
containerRef,
} = useMenuNavigation({
items,
getItemSubMenu,
addLevel: addCurrentLevel,
active: activeLevelDepth === levelDepth,
deleteLevel: () => deleteLevel(levelDepth),
onEsc: handleEscClick,
level: levelDepth,
isMobile,
});

const itemsRefs = useMemo(() => {
return items
.map((item) => getKey(item))
.reduce((a, v, index) => ({ ...a, [v]: refs[index] }), {}) as Record<
string,
React.RefObject<HTMLDivElement>
>;
}, [groupsProp, refs]);

const activeKey = useMemo(() => {
const item = items[activeIndex];
return item ? getKey(item) : undefined;
}, [items, activeIndex]);

const onMouseEnter = isMobile
? undefined
: (item: ContextMenuItemDefault): AsTagAttribute<'div'>['onMouseEnter'] =>
(e) => {
addCurrentLevel(item);
const onMouseEnter = getItemAttributes(item)
const onMouseEnter = getItemAttributesProp(item)
?.onMouseEnter as AsTagAttribute<'div'>['onMouseEnter'];

setActiveIndex(items.indexOf(item));
onMouseEnter?.(e);
};

const firstLevel = levelDepth === 0;
// GETTERS

const getItemOnClick = getItemOnClickProp
? (item: ContextMenuItemDefault) => (e: React.MouseEvent) => {
getItemOnClickProp(item)?.({
e: e as React.MouseEvent<HTMLDivElement>,
item,
});
}
: undefined;

const getItemAttributes = (item: ContextMenuItemDefault) =>
({
...getItemAttributesProp(item),
tabIndex: 0,
onMouseEnter: onMouseEnter?.(item),
} as AsAttributes);

const getItemActive = (item: ContextMenuItemDefault) => {
const key = getKey(item);
return key === activeItem || key === activeKey;
};

const getItemRightSide = (item: ContextMenuItemDefault) => {
const side = getItemRightSideProp(item);
if (!getItemSubMenu(item)) {
return side;
}

const sides: React.ReactNode[] = Array.isArray(side) ? side : [side];
sides.push(<IconArrowRight size={mapIconSize[size]} />);
return sides;
};

const onMouseLeave: React.MouseEventHandler = () => {
setHovered.off();
setActiveIndex(-1);
};

const onItemClick: ListPropOnItemClick<ContextMenuItemDefault> = (
item,
{ e },
) => {
if (isMobile) {
addCurrentLevel(item);
setActiveIndex(items.indexOf(item));
}
onItemClickProp?.({
item,
e: e as React.MouseEvent<HTMLDivElement>,
});
};

// EFFECTS

useEffect(() => {
if (levelDepth !== 0 && !hovered && hoveredParenLevel < levelDepth) {
clearTimeout(timers[levelDepth]);
timers[levelDepth] = setTimeout(
() => deleteLevel(levelDepth),
closeDelay,
);
}
return () => clearTimeout(timers[levelDepth]);
}, [hovered, hoveredParenLevel]);

useEffect(() => {
if (!isOpen) {
clearTimeout(timers[levelDepth]);
}
}, [isOpen]);

return (
<ContextMenuLevelWrapper
Expand All @@ -168,10 +260,15 @@ const ContextMenuLevelRender = (
spareDirection={spareDirection}
direction={direction}
offset={offset}
onSetDirection={onSetDirection}
tabIndex={0}
onKeyDown={onKeyDown}
onSetDirection={(direction) => {
onSetDirection?.(direction);
setDirection(direction);
}}
onMouseEnter={setHovered.on}
onMouseLeave={setHovered.off}
ref={ref}
onMouseLeave={onMouseLeave}
ref={useForkRef([ref, containerRef])}
isMobile={isMobile}
{...otherProps}
>
Expand All @@ -180,8 +277,14 @@ const ContextMenuLevelRender = (
<ListItem
label={getItemLabel(parent)}
size={size}
tabIndex={0}
ref={parentRef}
leftIcon={IconArrowLeft}
onClick={() => deleteLevel(levelDepth)}
active={activeIndex === -1}
className={cnContextMenuLevel('Item', {
active: activeIndex === -1,
})}
/>
<ListDivider size={size} space={{ mV: mapVerticalSpase[size] }} />
</>
Expand All @@ -190,54 +293,28 @@ const ContextMenuLevelRender = (
size={size}
items={items}
getItemLabel={getItemLabel}
onItemClick={(item, { e }) => {
isMobile && addCurrentLevel(item);
onItemClick?.({
item,
e: e as React.MouseEvent<HTMLDivElement>,
});
}}
onItemClick={onItemClick}
sortGroup={sortGroup ? (a, b) => sortGroup(a.key, b.key) : undefined}
getItemOnClick={
getItemOnClick
? (item) => (e) =>
getItemOnClick(item)?.({
e: e as React.MouseEvent<HTMLDivElement>,
item,
})
: undefined
}
getItemOnClick={getItemOnClick}
getItemAs={getItemAs}
getItemAttributes={
onMouseEnter
? (item) =>
({
...getItemAttributes(item),
onMouseEnter: onMouseEnter(item),
} as AsAttributes)
: getItemAttributes
}
getItemAttributes={getItemAttributes}
getItemGroupKey={getItemGroupId}
getItemLeftIcon={getItemLeftIcon}
getItemRightIcon={getItemRightIcon}
getItemLeftSide={getItemLeftSide}
getItemRightSide={(item) => {
const side = getItemRightSide(item);
if (!getItemSubMenu(item)) {
return side;
}

const sides: React.ReactNode[] = Array.isArray(side) ? side : [side];
sides.push(<IconArrowRight size={mapIconSize[size]} />);
return sides;
}}
getItemRightSide={getItemRightSide}
getGroupKey={getGroupId}
getGroupLabel={getGroupLabel}
getItemDisabled={getItemDisabled}
getItemStatus={getItemStatus}
getItemActive={getItemActive}
getItemAdditionalClassName={(item) =>
cnContextMenuLevel('Item', {
active: getKey(item) === activeItem,
})
}
getItemRef={(item) => itemsRefs[getKey(item)]}
groups={groupsProp}
getItemActive={(item) => getKey(item) === activeItem}
innerOffset={form === 'round' ? 'increased' : 'normal'}
/>
</ContextMenuLevelWrapper>
Expand Down
Loading

0 comments on commit 94a0b0e

Please sign in to comment.