Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Table)!: update SortIndicator view #1220

Merged
merged 4 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
$block: '.#{variables.$ns}sort-indicator';

#{$block} {
&__caret {
padding: 1px 0;

& > svg {
display: block;
}
&__icon {
vertical-align: -2px;
Raubzeug marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';

import {ArrowDown, ArrowUp, ArrowUpArrowDown} from '@gravity-ui/icons';

import {Icon} from '../../../../Icon';
import {block} from '../../../../utils/cn';
import {a11yHiddenSvgProps} from '../../../../utils/svg';

import './SortIndicator.scss';

Expand All @@ -11,23 +13,22 @@ export interface SortIndicatorProps {

const b = block('sort-indicator');

export function SortIndicator({order = 'asc'}: SortIndicatorProps) {
export function SortIndicator({order}: SortIndicatorProps) {
let icon;
switch (order) {
case 'asc':
icon = ArrowUp;
break;
case 'desc':
icon = ArrowDown;
break;
default:
icon = ArrowUpArrowDown;
}

return (
<div className={b()}>
<div
className={b('caret')}
style={{transform: order === 'asc' ? 'scale(1, -1)' : undefined}}
>
<svg
width="6"
height="3"
viewBox="0 0 6 3"
fill="currentColor"
{...a11yHiddenSvgProps}
>
<path d="M0.404698 0C0.223319 0 0.102399 0.0887574 0.0419396 0.230769C-0.0386733 0.372781 0.00163315 0.497041 0.122552 0.60355L2.72232 2.89349C2.80293 2.9645 2.88354 3 3.00446 3C3.10523 3 3.20599 2.9645 3.28661 2.89349L5.88637 0.60355C6.00729 0.497041 6.02745 0.372781 5.96699 0.230769C5.88637 0.0887574 5.76545 0 5.60423 0H0.404698Z" />
</svg>
</div>
<Icon data={icon} size={14} className={b('icon')} />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,25 @@ $block: '.#{variables.$ns}table';
#{$block} {
&__sort {
display: inline-flex;
align-items: center;
align-items: baseline;
gap: var(--g-spacing-1);
// `top` to avoid redundant height to appear
vertical-align: top;
cursor: pointer;
user-select: none;

&-spacer {
width: 5px;
}
border-radius: var(--g-border-radius-xs);
Raubzeug marked this conversation as resolved.
Show resolved Hide resolved

&-indicator {
flex-shrink: 0;
color: var(--g-color-text-hint);
opacity: 0;
}

&_active &-indicator {
color: var(--g-color-text-primary);
opacity: 1;
}

&:hover &-indicator {
opacity: 1;
&:focus-visible {
outline: 2px solid var(--g-color-line-focus);
}
}
}
15 changes: 9 additions & 6 deletions src/components/Table/hoc/withTableSorting/withTableSorting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';

import _memoize from 'lodash/memoize';

import {createOnKeyDownHandler} from '../../../../hooks/useActionHandlers/useActionHandlers';
import {block} from '../../../utils/cn';
import {getComponentName} from '../../../utils/getComponentName';
import {Table} from '../../Table';
Expand Down Expand Up @@ -135,23 +136,25 @@ export function withTableSorting<I extends TableDataItem, E extends {} = {}>(
<div key="content" className={b('sort-content')}>
{originContent}
</div>,
<div key="spacer" className={b('sort-spacer')} />,
<div key="indicator" className={b('sort-indicator')}>
<SortIndicator
order={sortOrder || this.getColumnDefaultSortOrder(column)}
/>
<SortIndicator order={sortOrder} />
</div>,
];

if (column.align === 'right' || column.align === 'end') {
content.reverse();
}

const onClick = this.handleColumnSortClick.bind(this, column);
const onKeyDown = createOnKeyDownHandler(onClick);

return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div
role="button"
tabIndex={0}
className={b('sort', {active: Boolean(sortOrder)})}
onClick={this.handleColumnSortClick.bind(this, column)}
onClick={onClick}
onKeyDown={onKeyDown}
>
{content}
</div>
Expand Down
25 changes: 12 additions & 13 deletions src/hooks/useActionHandlers/useActionHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react';

import {KeyCode} from '../../constants';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type AnyFunction = (...args: any[]) => any;

export type UseActionHandlersProps = AnyFunction;
Expand All @@ -11,6 +10,17 @@ export interface UseActionHandlersResult<T> {
onKeyDown: React.KeyboardEventHandler<T>;
}

export function createOnKeyDownHandler<T>(callback?: AnyFunction) {
return (event: React.KeyboardEvent<T>) => {
if (
callback &&
[KeyCode.ENTER, KeyCode.SPACEBAR, KeyCode.SPACEBAR_OLD].includes(event.key)
) {
callback(event);
}
};
}

/**
* Emulates behaviour of system controls, that respond to Enter and Spacebar
* @param callback
Expand All @@ -19,18 +29,7 @@ export interface UseActionHandlersResult<T> {
export function useActionHandlers<T>(
callback?: UseActionHandlersProps,
): UseActionHandlersResult<T> {
const onKeyDown = React.useCallback(
(event: React.KeyboardEvent<T>) => {
if (
callback &&
[KeyCode.ENTER, KeyCode.SPACEBAR, KeyCode.SPACEBAR_OLD].includes(event.key)
) {
// eslint-disable-next-line callback-return
callback(event);
}
},
[callback],
);
const onKeyDown = React.useMemo(() => createOnKeyDownHandler<T>(callback), [callback]);

return {onKeyDown};
}
Loading