-
Notifications
You must be signed in to change notification settings - Fork 2
[FRNT-532, FRNT-532] Implement box model, rewrite ButtonIcon and Chip #109
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import * as React from 'react'; | ||
import styled, { StyledComponent } from 'styled-components'; | ||
import { Variant } from 'lib/types'; | ||
import { box } from 'ui/elements/quarks'; | ||
|
||
interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> { | ||
className?: string; | ||
|
@@ -22,24 +23,38 @@ const ButtonIconBase: React.FC<Props & Variant> = ({ | |
); | ||
|
||
export const ButtonIcon = styled(ButtonIconBase)` | ||
${box} | ||
--local-vertical: calc( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Может унести local-vertical внутрь box? |
||
1px * var(--woly-component-level) * var(--woly-main-level) | ||
); | ||
|
||
--local-shape-color: var(--woly-canvas-default); | ||
--local-icon-size: var(--woly-line-height); | ||
--local-icon-color: var(--woly-canvas-text-default); | ||
--local-padding: calc(1px * var(--woly-component-level) * var(--woly-main-level)); | ||
--local-icon-size: calc(var(--woly-line-height)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а зачем тут calc? |
||
--local-button-size: calc(var(--local-icon-size) + (var(--local-vertical) * 2)); | ||
--local-icon-color: var(--woly-shape-default); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. цвета не меняла, ток у Chip чуть поправила чтоб его видно было и удобно было смотреть, но пока не как в макетах, задачи такой не стояло There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а есть смысл заводить задачу только на то, чтобы 1 переменную для цвета поменять? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. по идее надо две задачи, для чипа проверить все цвета для вариантов и для иконок. плюс из такого что щас вижу - у иконок еще появилась подложка с прозрачностью. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ты просто в этой таске уже начала рефакторить цвета иконки, тут тогда не надо было совсем этого делать |
||
|
||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
box-sizing: border-box; | ||
|
||
border: var(--woly-border) solid var(--local-shape-color); | ||
border-radius: var(--woly-rounding, 4px); | ||
width: var(--local-button-size); | ||
height: var(--local-button-size); | ||
|
||
border: var(--woly-border-width) solid var(--local-shape-color); | ||
border-radius: var(--woly-rounding); | ||
cursor: pointer; | ||
padding: var(--local-padding); | ||
background: var(--local-shape-color); | ||
outline: none; | ||
|
||
[data-icon] { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
width: var(--local-icon-size); | ||
height: var(--local-icon-size); | ||
svg { | ||
width: var(--local-icon-size); | ||
height: var(--local-icon-size); | ||
} | ||
|
||
svg > path { | ||
fill: var(--local-icon-color); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,197 +1,96 @@ | ||
import * as React from 'react'; | ||
import styled, { StyledComponent } from 'styled-components'; | ||
import { Variant } from 'lib/types'; | ||
|
||
/** | ||
* --woly-rounding — in pixels | ||
* --woly-font-size | ||
* --woly-line-height | ||
* --woly-border-width | ||
* | ||
* --woly-background | ||
* --woly-border | ||
* --woly-color | ||
* | ||
* --woly-background-hover | ||
* --woly-border-hover | ||
* --woly-color-hover | ||
* | ||
* --woly-background-focus | ||
* --woly-border-focus | ||
* --woly-color-focus | ||
* | ||
* --woly-background-disabled | ||
* --woly-border-disabled | ||
* --woly-color-disabled | ||
* | ||
*/ | ||
import { box } from 'ui/elements/quarks'; | ||
|
||
interface ChipProps { | ||
action?: React.ReactNode; | ||
children?: string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. в этой ветке смотрим box-model, состояния как в макетах я не делала |
||
className?: string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ага, надо поправить, но в отдельной задаче по правке состояний чипа |
||
disabled?: boolean; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. да, для нулевого размера пока не знаю как cделать, в формулах gap = 0 и изза этого outline который выходит за ButtonIcon перекрывает текст There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. тут нет outline у icon, это подсвечивается сам chip, icon-button никак не меняется There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. тут дело не в icon-button, а в формуле компенсации для текста, у тебя текст может быть любой длины, при этом, иконка не должна залезать на него. Плюс у тебя сама иконка меньше по размерам, чем высота chip, а так не должно быть, по высоте они должны быть одинаковыми There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а я тут вижу что иконка в фокусе 👀 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут надо обсудить уже подробнее и мб с дизайнерами, потому что пока что реализовано, что если фокус на иконку то вся плашка чипа тоже в фокусе, и вроде с Димой Марисоным обсуждали это и он говорил что это ок. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. можем втроем поглядеть, чтобы никому обидно не было )) |
||
icon?: React.ReactNode; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
у тебя chip размера xs, то есть он должен быть по размеру как иконка === 24px, и в примере, где есть иконка она должна быть вплотную с границами chip, а вылезать за пределы должна только box-shadow => т.е. нужно вычесть ширину border, иначе он не будет соответствовать размерам icon-button и не будет вмещаться в input, к примеру
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. для XS размер 30, это у размера N - 24px. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
onActionClick?: (event: React.MouseEvent<HTMLButtonElement>) => void; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. в чем вопрос? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. это скрин к комменту выше |
||
onClick?: (event: React.MouseEvent<HTMLDivElement>) => void; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. В нашей модели N = 24, XS = 30, S = 36, и тп There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ок ) выше написала коммент ) |
||
leftIcon?: React.ReactNode; | ||
onClick?: React.EventHandler<React.SyntheticEvent>; | ||
rightIcon?: React.ReactNode; | ||
} | ||
|
||
const ChipBase: React.FC<ChipProps & Variant> = ({ | ||
action, | ||
children, | ||
className, | ||
disabled, | ||
icon, | ||
onActionClick, | ||
leftIcon, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Зачем снова переименовывать иконки? Оно так называлось, потому что иконки имели разную принадлежность. Это не просто иконка слева и справа. Это иконка чипа и иконка действия. Если вдруг добавим rtl получится криво, что leftIcon внезапно начнет отображаться справа. Мне кажется, лучше переименовать обратно, или в chipIcon, actionIcon |
||
onClick, | ||
rightIcon, | ||
variant = 'secondary', | ||
}) => { | ||
const chipRole = onClick ? 'button' : 'div'; | ||
const chipTabIndex = onClick ? 1 : 0; | ||
const chipTabIndex = onClick ? 0 : -1; | ||
|
||
const onKeyDown = React.useCallback( | ||
(event) => { | ||
if (event.key === 'Enter' && onClick) { | ||
onClick(event); | ||
} | ||
}, | ||
[onClick], | ||
); | ||
return ( | ||
<div className={className} data-disabled={disabled}> | ||
<div | ||
data-block="label" | ||
data-variant={variant} | ||
onClick={onClick} | ||
role={chipRole} | ||
tabIndex={chipTabIndex} | ||
> | ||
{icon && <div data-icon="left">{icon}</div>} | ||
<div className={className} data-disabled={disabled} data-variant={variant} role={chipRole}> | ||
{leftIcon && ( | ||
<div data-icon onClick={onClick} onKeyDown={onKeyDown}> | ||
{leftIcon} | ||
</div> | ||
)} | ||
<div data-text tabIndex={chipTabIndex} onClick={onClick} onKeyDown={onKeyDown}> | ||
{children} | ||
{action && ( | ||
<> | ||
<button | ||
data-icon="right" | ||
data-variant={variant} | ||
disabled={disabled} | ||
onClick={onActionClick} | ||
type="button" | ||
> | ||
{action} | ||
</button> | ||
<div data-type="stub" /> | ||
</> | ||
)} | ||
</div> | ||
{rightIcon && <div data-icon>{rightIcon}</div>} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Иконка справа это действие с чипом, обычно закрытие. |
||
</div> | ||
); | ||
}; | ||
|
||
export const Chip = styled(ChipBase)` | ||
--woly-vertical: calc(1px * var(--woly-component-level) * var(--woly-main-level)); | ||
--woly-horizontal: calc( | ||
var(--woly-const-m) + (1px * var(--woly-main-level)) + var(--woly-vertical) | ||
); | ||
--woly-line-height: 24px; | ||
|
||
position: relative; | ||
${box} | ||
--local-background: var(--woly-shape-default); | ||
--local-icon-size: var(--woly-line-height); | ||
--local-color: var(--woly-shape-text-default); | ||
--local-border-color: var(--woly-shape-default); | ||
|
||
box-sizing: border-box; | ||
|
||
display: flex; | ||
align-items: center; | ||
|
||
background-color: var(--woly-background, #b0a3f4); | ||
color: var(--woly-color, #ffffff); | ||
|
||
border-radius: var(--woly-rounding, 3px); | ||
|
||
[role] { | ||
width: 100%; | ||
|
||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
|
||
font-size: var(--woly-font-size, 12px); | ||
line-height: var(--woly-line-height, 20px); | ||
|
||
border-radius: var(--woly-rounding, 3px); | ||
|
||
padding: 0 var(--woly-horizontal, 6px); | ||
|
||
background-color: var(--local-background); | ||
color: var(--local-color); | ||
border-radius: var(--woly-rounding); | ||
font-size: var(--woly-font-size); | ||
outline: none; | ||
border: var(--woly-border-width) solid var(--local-border-color); | ||
|
||
[data-text] { | ||
outline: none; | ||
line-height: var(--woly-line-height); | ||
} | ||
|
||
[role='button']:active { | ||
color: var(--woly-color-focus, #ffffff); | ||
background-color: var(--woly-background-focus, #9381f1); | ||
border-color: var(--woly-border-focus, transparent); | ||
} | ||
&[role='button']:focus-within { | ||
--local-background: var(--woly-focus); | ||
--local-border-color: var(--woly-shape-active); | ||
|
||
[role='button']:focus { | ||
box-shadow: 0 0 0 var(--woly-border-width) var(--woly-border-focus, #9381f1); | ||
box-shadow: 0 0 0 var(--woly-border-width) var(--woly-shape-default); | ||
} | ||
|
||
[role='button']:hover { | ||
color: var(--woly-color-hover, #ffffff); | ||
background-color: var(--woly-background-hover, #9381f1); | ||
opacity: 0.5; | ||
border-color: var(--woly-border-hover, transparent); | ||
outline: none; | ||
&[role='button']:hover { | ||
--local-background: var(--woly-shape-hover); | ||
--local-border-color: var(--woly-shape-hover); | ||
} | ||
|
||
&[data-disabled='true'] { | ||
color: var(--woly-color-disabled, #c0c0c0); | ||
background: var(--woly-background-disabled, #f5f5f5); | ||
border-color: var(--woly-background-disabled, transparent); | ||
pointer-events: none; | ||
--local-background: var(--woly-shape-disabled); | ||
--local-text: var(--woly-shape-text-disabled); | ||
--local-border-color: var(--woly-shape-disabled); | ||
|
||
[data-icon] { | ||
svg > path { | ||
fill: var(--woly-color, #c0c0c0); | ||
} | ||
} | ||
pointer-events: none; | ||
} | ||
|
||
[data-icon], | ||
[data-type='stub'] { | ||
[data-icon] { | ||
--woly-component-level: 0; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
|
||
width: var(--woly-line-height, 24px); | ||
height: var(--woly-line-height, 24px); | ||
|
||
background: var(--woly-background-disabled, transparent); | ||
|
||
border-color: var(--woly-border, transparent); | ||
border-style: solid; | ||
border-width: var(--woly-border-width); | ||
border-radius: var(--woly-rounding, 3px); | ||
|
||
outline: none; | ||
|
||
svg > path { | ||
fill: var(--woly-color, #ffffff); | ||
} | ||
} | ||
|
||
[data-type='stub'] { | ||
visibility: hidden; | ||
position: static; | ||
flex-shrink: 0; | ||
} | ||
|
||
[data-icon='right'] { | ||
position: absolute; | ||
right: 0; | ||
z-index: 1; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
|
||
&:hover { | ||
background-color: var(--woly-background-hover, #9381f1); | ||
opacity: 0.5; | ||
} | ||
|
||
&:active { | ||
background-color: var(--woly-background-hover, #9381f1); | ||
} | ||
|
||
&:focus { | ||
box-shadow: 0 0 0 var(--woly-border-width) var(--woly-border-focus, #9381f1); | ||
} | ||
} | ||
` as StyledComponent<'div', Record<string, unknown>, ChipProps & Variant>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тот же комментарий что и в https://github.com/woly-ui/woly/pull/110/files#r628142059