Skip to content

Commit

Permalink
feat(Label): add closeButtonLabel prop (#292)
Browse files Browse the repository at this point in the history
* use `<Button/>` for `type=close` appearance
* add `closeButtonLabel` prop to customize button `aria-label`
  • Loading branch information
ogonkov authored Aug 5, 2022
1 parent d48b1b9 commit 5b6499d
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 39 deletions.
21 changes: 15 additions & 6 deletions src/components/Label/Label.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ $transitionTimingFunction: ease-in-out;

& #{$block}__icon {
&_cross {
border-radius: 0 4px 4px 0;
--yc-button-height: 20px;
--yc-button-border-radius: 4px;
}
}
}
Expand Down Expand Up @@ -107,7 +108,8 @@ $transitionTimingFunction: ease-in-out;

& #{$block}__icon {
&_cross {
border-radius: 0 4px 4px 0;
--yc-button-height: 28px;
--yc-button-border-radius: 4px;
}
}
}
Expand All @@ -117,7 +119,8 @@ $transitionTimingFunction: ease-in-out;

& #{$block}__icon {
&_cross {
border-radius: 0 24px 24px 0;
--yc-button-height: 28px;
--yc-button-border-radius: 24px;
}
}
}
Expand Down Expand Up @@ -157,9 +160,15 @@ $transitionTimingFunction: ease-in-out;
}

// hover на крестик
&:not(#{$disabled}) #{$block}__icon_cross:hover {
color: var(--yc-color-text-inverted-primary);
background-color: var(--yc-color-base-misc-heavy-hover);
&:not(#{$disabled}) #{$block}__icon_cross {
--yc-button-background-color: transparent;
--yc-button-background-color-hover: var(--yc-color-base-misc-heavy-hover);

color: inherit;

&:hover {
color: var(--yc-color-text-inverted-primary);
}
}
}

Expand Down
43 changes: 25 additions & 18 deletions src/components/Label/Label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,42 @@ import {CopyToClipboard, CopyToClipboardStatus} from '../CopyToClipboard';
import {ClipboardIcon} from '../ClipboardIcon';
import {Icon} from '../Icon';
import {CrossIcon} from '../icons/CrossIcon';
import {Button} from '../Button';
import './Label.scss';

const b = block('label');

interface LabelOwnProps {
/** Иконка лейбла (слева) */
/** Label icon (at left) */
icon?: React.ReactNode;
/** Состояние disabled */
/** Disabled state */
disabled?: boolean;
/** Хендлер на нажатие крестика */
onClose?(event: React.MouseEvent<HTMLDivElement>): void;
/** Текст для копирования */
/** Handler for click on button with cross */
onClose?(event: React.MouseEvent<HTMLButtonElement>): void;
/** Text to copy */
copyText?: string;
/** Хендлер после события копирования */
/* `aria-label` of button with cross */
closeButtonLabel?: string;
/** Handler for copy event */
onCopy?(text: string, result: boolean): void;
/** Хендлер на клик на лейбл */
/** Handler for click on label itself */
onClick?(event: React.MouseEvent<HTMLDivElement>): void;
/** Дополнительный класс */
/** Class name */
className?: string;
/** Содержимое */
/** Content */
children?: React.ReactNode;
/** Добавить ховер */
/** Display hover */
interactive?: boolean;
}

interface LabelDefaultProps {
/** Цвет лейбла */
/** Label color */
theme: 'normal' | 'info' | 'danger' | 'warning' | 'success' | 'unknown';
/** Тип лейбла (обычный, с текстом для копирования или с крестиком) */
/** Label type (plain, with copy text button or button with cross) */
type: 'default' | 'copy' | 'close';
/** Размер лейбла */
/** Label size */
size: 's' | 'm';
/** Стиль кнопки (с загруленными краями или обычная) */
/** Label appearance (with round corners or plain) */
style: 'rounded' | 'default';
}

Expand All @@ -54,6 +57,7 @@ export const Label = React.forwardRef<HTMLDivElement, LabelProps>(function Label
className,
disabled,
copyText,
closeButtonLabel,
interactive = false,
onCopy,
onClick,
Expand All @@ -63,7 +67,7 @@ export const Label = React.forwardRef<HTMLDivElement, LabelProps>(function Label
const typeClose = type === 'close';
const typeCopy = type === 'copy';

// Обрабатываем onClick только у лейблов с типом default
// Handle click for `default` type labels
const hasOnClick = Boolean(onClick) && typeDefault;
const isInteractive = hasOnClick || interactive;
const hasAction = typeClose || typeCopy;
Expand Down Expand Up @@ -100,15 +104,18 @@ export const Label = React.forwardRef<HTMLDivElement, LabelProps>(function Label
};

const closeButton = typeClose && (
<div
<Button
onClick={onClose}
pin={'brick-round'}
size={size}
extraProps={{'aria-label': closeButtonLabel || undefined}}
className={b('icon', {
right: true,
cross: true,
})}
>
<Icon size={closeIconSize} data={CrossIcon} />
</div>
</Button>
);

const renderLabel = (status?: CopyToClipboardStatus) => {
Expand All @@ -118,7 +125,7 @@ export const Label = React.forwardRef<HTMLDivElement, LabelProps>(function Label
onClick={hasOnClick ? onClick : undefined}
className={b(
{
// на данный момент лейблы с действиями могут быть только дефолтными
// only default labels could have actions
theme: hasAction ? 'normal' : theme,
size,
style,
Expand Down
41 changes: 26 additions & 15 deletions src/components/Label/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
### PropTypes
# Label

| Property | Type | Required | Default | Description |
| :-------- | :--------------------------------------------------------- | :------- | :---------- | :------------------------------------------------------- |
| theme | `String` | | `normal ` | Label appearance |
| type | `String` | | `default` | Label type (plain, with text to copy or with cross icon) |
| size | `String` | | `xs` | Label size |
| style | `String` | | `default` | Button style (default or rounded corners) |
| tooltip | `TooltipProps` | | `undefined` | Tooltip |
| icon | `ReactNode` | | `undefined` | Icon at the left |
| disabled | `Boolean` | | `undefined` | disabled state |
| onClose | `onClose?(event: React.MouseEvent<HTMLDivElement>): void;` | | `undefined` | Button with cross handler |
| copyText | `String` | | `undefined` | Text to copy |
| onCopy | `onCopy?(text: string, result: boolean): void;` | | `undefined` | Callback after copy |
| onClick | `onClose?(event: React.MouseEvent<HTMLDivElement>): void;` | | `undefined` | Handler for element click |
| className | `String` | | `undefined` | Class name |
## PropTypes

| Property | Type | Required | Default | Description |
| :--------------- | :--------------------------------------------------------- | :------- | :---------- | :------------------------------------------------------- |
| theme | `String` | | `normal ` | Label appearance |
| type | `String` | | `default` | Label type (plain, with text to copy or with cross icon) |
| size | `String` | | `xs` | Label size |
| style | `String` | | `default` | Button style (default or rounded corners) |
| tooltip | `TooltipProps` | | `undefined` | Tooltip |
| icon | `ReactNode` | | `undefined` | Icon at the left |
| disabled | `Boolean` | | `undefined` | disabled state |
| onClose | `onClose?(event: React.MouseEvent<HTMLDivElement>): void;` | | `undefined` | Button with cross handler |
| copyText | `String` | | `undefined` | Text to copy |
| closeButtonLabel | `String` | | `undefined` | Text of `aria-label` of button with cross |
| onCopy | `onCopy?(text: string, result: boolean): void;` | | `undefined` | Callback after copy |
| onClick | `onClose?(event: React.MouseEvent<HTMLDivElement>): void;` | | `undefined` | Handler for element click |
| className | `String` | | `undefined` | Class name |

## Example

```tsx
<Label type="close" closeButtonLabel='Remove tag "Foobar"' onClose={removeTag}>
Foobar
</Label>
```

0 comments on commit 5b6499d

Please sign in to comment.