diff --git a/packages/react-components/src/components/Avatar/Avatar.module.scss b/packages/react-components/src/components/Avatar/Avatar.module.scss
index ee5cc07aa..97b5604e0 100644
--- a/packages/react-components/src/components/Avatar/Avatar.module.scss
+++ b/packages/react-components/src/components/Avatar/Avatar.module.scss
@@ -1,21 +1,21 @@
$base-class: 'avatar';
.#{$base-class} {
+ display: flex;
+ position: relative;
align-items: center;
+ justify-content: center;
background-color: var(--surface-basic-disabled);
- display: flex;
font-weight: 600;
- justify-content: center;
- position: relative;
&__status {
$status-class: &;
$circle-class: #{$status-class}--circle;
$rounded-square-class: #{$status-class}--rounded-square;
+ position: absolute;
border: 1px solid var(--background);
border-radius: 50%;
- position: absolute;
&--available {
background: var(--color-positive-default);
@@ -55,71 +55,71 @@ $base-class: 'avatar';
&--xxxsmall {
border-width: calc(4px * 0.125);
- height: 4px;
width: 4px;
+ height: 4px;
}
&--xxsmall {
border-width: calc(5px * 0.125);
- height: 5px;
width: 5px;
+ height: 5px;
}
&--xsmall {
border-width: calc(6px * 0.125);
- height: 6px;
width: 6px;
+ height: 6px;
}
&--small {
border-width: calc(8px * 0.125);
- height: 8px;
width: 8px;
+ height: 8px;
}
&--medium {
border-width: calc(8px * 0.125);
- height: 9px;
width: 9px;
+ height: 9px;
}
&--large {
border-width: calc(12px * 0.125);
- height: 12px;
width: 12px;
+ height: 12px;
}
&--xlarge {
border-width: calc(16px * 0.125);
- height: 16px;
width: 16px;
+ height: 16px;
}
&--xxlarge {
border-width: calc(24px * 0.125);
- height: 24px;
width: 24px;
+ height: 24px;
}
}
&__rim {
- background: transparent;
- border-color: var(--color-negative-default);
- border-radius: inherit;
- border-style: solid;
box-sizing: content-box;
display: block;
- left: 50%;
position: absolute;
top: 50%;
+ left: 50%;
transform: translate(-50%, -50%);
+ border-style: solid;
+ border-radius: inherit;
+ border-color: var(--color-negative-default);
+ background: transparent;
&--xxxsmall,
&--xxsmall,
&--xsmall {
border-width: 2px;
- height: calc(100% + 2px);
width: calc(100% + 2px);
+ height: calc(100% + 2px);
}
&--small,
@@ -128,57 +128,57 @@ $base-class: 'avatar';
&--xlarge,
&--xxlarge {
border-width: 3px;
- height: calc(100% + 4px);
width: calc(100% + 4px);
+ height: calc(100% + 4px);
}
}
&__image {
border-radius: inherit;
+ width: 100%;
height: 100%;
object-fit: cover;
- width: 100%;
}
&__icon {
&--xxxsmall svg {
- height: 8px;
width: 8px;
+ height: 8px;
}
&--xxsmall svg {
- height: 10px;
width: 10px;
+ height: 10px;
}
&--xsmall svg {
- height: 12px;
width: 12px;
+ height: 12px;
}
&--small svg {
- height: 16px;
width: 16px;
+ height: 16px;
}
&--medium svg {
- height: 18px;
width: 18px;
+ height: 18px;
}
&--large svg {
- height: 24px;
width: 24px;
+ height: 24px;
}
&--xlarge svg {
- height: 32px;
width: 32px;
+ height: 32px;
}
&--xxlarge svg {
- height: 48px;
width: 48px;
+ height: 48px;
}
}
@@ -205,58 +205,58 @@ $base-class: 'avatar';
}
&--xxxsmall {
- font-size: 12px;
+ width: 16px;
height: 16px;
line-height: 20px;
- width: 16px;
+ font-size: 12px;
}
&--xxsmall {
- font-size: 12px;
+ width: 20px;
height: 20px;
line-height: 20px;
- width: 20px;
+ font-size: 12px;
}
&--xsmall {
- font-size: 12px;
+ width: 24px;
height: 24px;
line-height: 20px;
- width: 24px;
+ font-size: 12px;
}
&--small {
- font-size: 15px;
+ width: 32px;
height: 32px;
line-height: 22px;
- width: 32px;
+ font-size: 15px;
}
&--medium {
- font-size: 15px;
+ width: 36px;
height: 36px;
line-height: 22px;
- width: 36px;
+ font-size: 15px;
}
&--large {
- font-size: 18px;
+ width: 48px;
height: 48px;
line-height: 24px;
- width: 48px;
+ font-size: 18px;
}
&--xlarge {
- font-size: 24px;
+ width: 64px;
height: 64px;
line-height: 32px;
- width: 64px;
+ font-size: 24px;
}
&--xxlarge {
- font-size: 32px;
+ width: 96px;
height: 96px;
line-height: 40px;
- width: 96px;
+ font-size: 32px;
}
}
diff --git a/packages/react-components/src/components/Button/Button.tsx b/packages/react-components/src/components/Button/Button.tsx
index 97fe2f043..326082e82 100644
--- a/packages/react-components/src/components/Button/Button.tsx
+++ b/packages/react-components/src/components/Button/Button.tsx
@@ -1,10 +1,9 @@
import * as React from 'react';
import cx from 'clsx';
import { Loader } from '../Loader';
-
+import { Size } from 'utils';
import styles from './Button.module.scss';
-export type ButtonSize = 'compact' | 'medium' | 'large';
export type ButtonKind =
| 'basic'
| 'primary'
@@ -16,7 +15,7 @@ export type ButtonKind =
export type ButtonProps = {
kind?: ButtonKind;
- size?: ButtonSize;
+ size?: Size;
disabled?: boolean;
loading?: boolean;
fullWidth?: boolean;
diff --git a/packages/react-components/src/components/Button/index.ts b/packages/react-components/src/components/Button/index.ts
index 182d82688..476273b8e 100644
--- a/packages/react-components/src/components/Button/index.ts
+++ b/packages/react-components/src/components/Button/index.ts
@@ -1,2 +1,2 @@
export { Button } from './Button';
-export type { ButtonSize, ButtonKind, ButtonProps } from './Button';
+export type { ButtonKind, ButtonProps } from './Button';
diff --git a/packages/react-components/src/components/DatePicker/DatePicker.module.scss b/packages/react-components/src/components/DatePicker/DatePicker.module.scss
index 2fc7d579d..ad163a5fa 100644
--- a/packages/react-components/src/components/DatePicker/DatePicker.module.scss
+++ b/packages/react-components/src/components/DatePicker/DatePicker.module.scss
@@ -1,22 +1,30 @@
$base-class: 'date-picker';
.#{$base-class} {
- color: var(--content-default);
display: inline-block;
+ color: var(--content-default);
+
+ &:not(.#{$base-class}--interaction-disabled)
+ &__day:not(.#{$base-class}__day--disabled):not(.#{$base-class}__day--selected):not(.#{$base-class}__day--outside):hover {
+ .#{$base-class}__day-content {
+ border-radius: 2px;
+ background-color: var(--surface-basic-hover);
+ }
+ }
&__wrapper {
- border: 1px solid transparent;
- flex-direction: row;
- padding-bottom: 10px;
position: relative;
+ flex-direction: row;
transition: 0.2s border-color ease-in-out;
+ border: 1px solid transparent;
+ padding-bottom: 10px;
user-select: none;
&:focus {
+ transition: 0.2s border-color ease-in-out;
+ outline: none;
border: 1px solid var(--color-action-default);
border-radius: 4px;
- outline: none;
- transition: 0.2s border-color ease-in-out;
}
}
@@ -34,23 +42,23 @@ $base-class: 'date-picker';
&__nav-bar {
display: flex;
- justify-content: space-between;
- left: 50%;
position: absolute;
top: 0;
+ left: 50%;
+ justify-content: space-between;
transform: translateX(-50%);
width: calc(100% - 18px);
}
&__nav-button {
+ display: flex;
align-content: center;
- background-color: transparent;
+ transition: 0.2s border-color ease-in-out;
border: 1px solid transparent;
- color: var(--content-subtle);
+ background-color: transparent;
cursor: pointer;
- display: flex;
padding: 0;
- transition: 0.2s border-color ease-in-out;
+ color: var(--content-subtle);
&:hover,
&:focus {
@@ -73,11 +81,11 @@ $base-class: 'date-picker';
padding: 0 50px;
> div {
+ text-align: center;
+ line-height: 20px;
color: var(--content-default);
font-size: 14px;
font-weight: 600;
- line-height: 20px;
- text-align: center;
}
}
@@ -90,14 +98,14 @@ $base-class: 'date-picker';
}
&__weekday {
- color: var(--content-subtle);
display: table-cell;
- font-size: 12px;
- letter-spacing: 0.2px;
- line-height: 16px;
margin-bottom: 2px;
padding: 6px 0;
text-align: center;
+ line-height: 16px;
+ letter-spacing: 0.2px;
+ color: var(--content-subtle);
+ font-size: 12px;
abbr[title] {
border-bottom: initial;
@@ -114,12 +122,12 @@ $base-class: 'date-picker';
}
&__day {
- color: var(--content-default);
- cursor: pointer;
display: table-cell;
- font-size: 14px;
- height: 18px;
+ cursor: pointer;
width: 18px;
+ height: 18px;
+ color: var(--content-default);
+ font-size: 14px;
&:focus {
outline: none;
@@ -136,37 +144,37 @@ $base-class: 'date-picker';
}
&-content {
- align-items: center;
display: flex;
- height: 28px;
+ align-items: center;
justify-content: center;
width: 28px;
+ height: 28px;
}
&--today {
.#{$base-class}__day-content {
- background-color: var(--surface-basic-default);
border-radius: 2px;
box-shadow: 0 0 0 1px var(--border-default);
+ background-color: var(--surface-basic-default);
}
}
&--selected {
.#{$base-class}__day-content {
- background-color: var(--color-action-default);
border-radius: 2px;
+ background-color: var(--color-action-default);
color: var(--content-invert-default);
}
}
&--outside {
- color: var(--content-disabled);
cursor: default;
+ color: var(--content-disabled);
}
&--disabled {
- color: var(--content-disabled);
cursor: default;
+ color: var(--content-disabled);
pointer-events: none;
}
}
@@ -194,28 +202,20 @@ $base-class: 'date-picker';
}
}
- &:not(.#{$base-class}--interaction-disabled)
- &__day:not(.#{$base-class}__day--disabled):not(.#{$base-class}__day--selected):not(.#{$base-class}__day--outside):hover {
- .#{$base-class}__day-content {
- background-color: var(--surface-basic-hover);
- border-radius: 2px;
- }
- }
-
&--range {
.#{$base-class}__day {
&--selected {
- .#{$base-class}__day-content {
- background-color: transparent;
- border-radius: 0;
- color: var(--content-default);
- }
&:not(.#{$base-class}__day--disabled):not(.#{$base-class}__day--outside):not(.#{$base-class}__day--start):not(.#{$base-class}__day--end):not(.#{$base-class}__day--single):not(.#{$base-class}__day--sunday):not(.#{$base-class}__day--monday) {
.#{$base-class}__day-wrapper {
background-color: var(--surface-feedback-info);
}
}
+ .#{$base-class}__day-content {
+ border-radius: 0;
+ background-color: transparent;
+ color: var(--content-default);
+ }
}
&--start:not(.#{$base-class}__day--end):not(.#{$base-class}__day--sunday):not(.#{$base-class}__day--monday),
@@ -254,8 +254,8 @@ $base-class: 'date-picker';
&--start,
&--end {
.#{$base-class}__day-content {
- background-color: var(--color-action-default);
border-radius: 2px;
+ background-color: var(--color-action-default);
color: var(--content-invert-default);
}
}
@@ -263,27 +263,27 @@ $base-class: 'date-picker';
&__select-input {
border-color: transparent;
- max-width: 90px;
padding: 0 5px;
+ max-width: 90px;
text-align: left;
}
&__calendars-wrapper {
- align-items: flex-start;
display: flex;
+ align-items: flex-start;
.#{$base-class}__months {
flex-wrap: nowrap;
margin: 0 -12px;
&::before {
- background-color: var(--border-subtle);
- content: '';
- height: 100%;
- left: 50%;
position: absolute;
top: 0;
+ left: 50%;
+ background-color: var(--border-subtle);
width: 1px;
+ height: 100%;
+ content: '';
}
}
diff --git a/packages/react-components/src/components/Icon/Icon.module.scss b/packages/react-components/src/components/Icon/Icon.module.scss
index 7c5d98972..5447fae5f 100644
--- a/packages/react-components/src/components/Icon/Icon.module.scss
+++ b/packages/react-components/src/components/Icon/Icon.module.scss
@@ -1,6 +1,6 @@
.icon {
- align-items: center;
display: flex;
+ align-items: center;
svg {
pointer-events: none;
diff --git a/packages/react-components/src/components/Input/Input.module.scss b/packages/react-components/src/components/Input/Input.module.scss
index 1897e0a0f..2cfd7387b 100644
--- a/packages/react-components/src/components/Input/Input.module.scss
+++ b/packages/react-components/src/components/Input/Input.module.scss
@@ -1,45 +1,86 @@
.input {
- background: var(--surface-basic-default);
+ box-sizing: border-box;
+ display: flex;
+ align-items: center;
+ outline: none;
border: 1px solid var(--border-default);
border-radius: 4px;
- box-sizing: border-box;
+ background: var(--surface-basic-default);
+ padding: 5px 12px;
+ line-height: 22px;
color: var(--content-default);
font-size: 15px;
- line-height: 22px;
- outline: none;
&::placeholder {
color: var(--content-disabled);
}
+ &:hover {
+ border-color: var(--border-hover);
+ }
+
&:focus {
border-color: var(--color-action-default);
}
&:disabled {
- background-color: var(--surface-basic-disabled);
border-color: var(--border-disabled);
+ background-color: var(--surface-basic-disabled);
color: var(--content-disabled);
}
- &--error {
- border-color: var(--color-negative-default);
+ &--focused,
+ &--focused:hover {
+ border-color: var(--color-action-default);
+ }
+
+ &--disabled,
+ &--disabled:hover {
+ border-color: var(--border-disabled);
+ background-color: var(--surface-basic-disabled);
+ }
+
+ input {
+ outline: none;
+ border: 0;
+ background: none;
+ padding: 0;
+ width: 100%;
+ color: var(--content-default);
}
- &--xsmall {
- height: 24px;
- padding: 1px 4px;
+ &--error,
+ &--error:hover {
+ border-color: var(--color-negative-default);
}
- &--small {
+
+ &--compact {
height: 32px;
- padding: 4px 8px;
}
+
&--medium {
height: 36px;
- padding: 6px 8px;
}
+
&--large {
height: 40px;
- padding: 8px;
+ }
+
+ &__icon {
+ &--disabled {
+ color: var(--content-disabled);
+ }
+
+ &--left {
+ margin-right: 9px;
+ }
+
+ &--right {
+ margin-left: 9px;
+ }
+ }
+
+ &__visibility-button {
+ margin-left: 9px;
}
}
diff --git a/packages/react-components/src/components/Input/Input.spec.tsx b/packages/react-components/src/components/Input/Input.spec.tsx
index dcb8d5c6b..9ba3f65ed 100644
--- a/packages/react-components/src/components/Input/Input.spec.tsx
+++ b/packages/react-components/src/components/Input/Input.spec.tsx
@@ -1,6 +1,8 @@
import * as React from 'react';
-import { render } from 'test-utils';
+import { fireEvent, render } from 'test-utils';
+import { AddCircle as AddCircleIcon } from '@livechat/design-system-icons/react/material';
import { Input } from './Input';
+import { Icon } from '../Icon';
import styles from './Input.module.scss';
@@ -15,23 +17,18 @@ describe(' component', () => {
expect(container.firstChild).toHaveClass(styles['input--medium']);
});
- it('should allow for xsmall size', () => {
- const { container } = render();
- expect(container.firstChild).toHaveClass(styles['input--xsmall']);
- });
-
- it('should allow for small size', () => {
- const { container } = render();
- expect(container.firstChild).toHaveClass(styles['input--small']);
+ it('should allow for compact size', () => {
+ const { container } = render();
+ expect(container.firstChild).toHaveClass(styles['input--compact']);
});
it('should allow for medium size', () => {
- const { container } = render();
+ const { container } = render();
expect(container.firstChild).toHaveClass(styles['input--medium']);
});
it('should allow for large size', () => {
- const { container } = render();
+ const { container } = render();
expect(container.firstChild).toHaveClass(styles['input--large']);
});
@@ -39,4 +36,81 @@ describe(' component', () => {
const { container } = render();
expect(container.firstChild).toHaveClass(styles['input--error']);
});
+
+ it('should have disabled class and input should be disabled if "disabled" prop is set', () => {
+ const { container, getByTestId } = render();
+ expect(container.firstChild).toHaveClass(styles['input--disabled']);
+ expect(container.firstChild).toHaveAttribute('aria-disabled', 'true');
+ expect(getByTestId('input')).toHaveAttribute('disabled');
+ });
+
+ it('should have custom placeholder text if it is set', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('input')).toHaveAttribute(
+ 'placeholder',
+ 'Custom placeholder'
+ );
+ });
+
+ it('should have text type input as default', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('input')).toHaveAttribute('type', 'text');
+ });
+
+ it('should have password type input if type "password" is set', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('input')).toHaveAttribute('type', 'password');
+ });
+
+ it('should change the input type if show password icon is clicked', () => {
+ const { getByTestId, getByRole } = render();
+ const input = getByTestId('input');
+ const button = getByRole('button');
+
+ expect(input).toHaveAttribute('type', 'password');
+ fireEvent.click(button);
+ expect(input).toHaveAttribute('type', 'text');
+ fireEvent.click(button);
+ expect(input).toHaveAttribute('type', 'password');
+ });
+
+ it('should render with icon from the left side', () => {
+ const { getByTestId } = render(
+ ,
+ place: 'left',
+ }}
+ />
+ );
+
+ expect(getByTestId('input-icon-left')).toBeVisible();
+ });
+
+ it('should render with icon from the right side', () => {
+ const { getByTestId } = render(
+ ,
+ place: 'right',
+ }}
+ />
+ );
+
+ expect(getByTestId('input-icon-right')).toBeVisible();
+ });
+
+ it('should not render with icon from the right side if type "password" is set', () => {
+ const { queryByTestId } = render(
+ ,
+ place: 'right',
+ }}
+ />
+ );
+
+ expect(queryByTestId('input-icon-right')).toBeFalsy();
+ });
});
diff --git a/packages/react-components/src/components/Input/Input.stories.tsx b/packages/react-components/src/components/Input/Input.stories.tsx
index 70f0b1aaa..74266aeb7 100644
--- a/packages/react-components/src/components/Input/Input.stories.tsx
+++ b/packages/react-components/src/components/Input/Input.stories.tsx
@@ -1,8 +1,9 @@
import * as React from 'react';
import { ComponentMeta, Story } from '@storybook/react';
+import { AddCircle as AddCircleIcon } from '@livechat/design-system-icons/react/material';
import { StoryDescriptor } from '../../stories/components/StoryDescriptor';
-
+import { Icon } from '../Icon';
import { Input, InputProps } from './Input';
const placeholderText = 'Placeholder text';
@@ -10,6 +11,9 @@ const placeholderText = 'Placeholder text';
export default {
title: 'Forms/Input',
component: Input,
+ argTypes: {
+ onChange: { action: 'changed' },
+ },
} as ComponentMeta;
export const Default: Story = (args: InputProps) => (
@@ -18,23 +22,20 @@ export const Default: Story = (args: InputProps) => (
Default.storyName = 'Input';
Default.args = {
- size: 'medium',
+ inputSize: 'medium',
placeholder: 'Placeholder text',
};
export const Sizes = (): JSX.Element => (
<>
-
-
-
-
-
+
+
-
+
-
+
>
);
@@ -49,3 +50,47 @@ export const States = (): JSX.Element => (
>
);
+
+export const Types = (): JSX.Element => (
+ <>
+
+
+
+
+
+
+ >
+);
+
+export const WithIcons = (): JSX.Element => (
+ <>
+
+ ,
+ place: 'left',
+ }}
+ placeholder={placeholderText}
+ />
+
+
+ ,
+ place: 'right',
+ }}
+ placeholder={placeholderText}
+ />
+
+
+ ,
+ place: 'left',
+ }}
+ placeholder={placeholderText}
+ type="password"
+ />
+
+ >
+);
diff --git a/packages/react-components/src/components/Input/Input.tsx b/packages/react-components/src/components/Input/Input.tsx
index db6cca22b..66ce1840b 100644
--- a/packages/react-components/src/components/Input/Input.tsx
+++ b/packages/react-components/src/components/Input/Input.tsx
@@ -1,34 +1,99 @@
import * as React from 'react';
import cx from 'clsx';
+import {
+ VisibilityOn as VisibilityOnIcon,
+ VisibilityOff as VisibilityOffIcon,
+} from '@livechat/design-system-icons/react/material';
+
+import { Size } from 'utils/constants';
import styles from './Input.module.scss';
+import { Button } from '../Button';
+import { Icon } from '../Icon';
-type InputSize = 'xsmall' | 'small' | 'medium' | 'large';
+interface InputIcon {
+ source: React.ReactElement;
+ place: 'left' | 'right';
+}
-export interface InputProps extends React.HTMLAttributes {
- size?: InputSize | undefined;
- error?: boolean | undefined;
- disabled?: boolean | undefined;
+export interface InputProps
+ extends React.InputHTMLAttributes {
+ inputSize?: Size;
+ error?: boolean;
+ disabled?: boolean;
+ icon?: InputIcon;
}
const baseClass = 'input';
+const renderIcon = (icon: InputIcon, disabled?: boolean) =>
+ React.cloneElement(icon.source, {
+ ['data-testid']: `input-icon-${icon.place}`,
+ className: cx(
+ styles[`${baseClass}__icon`],
+ styles[`${baseClass}__icon--${icon.place}`],
+ {
+ [styles[`${baseClass}__icon--disabled`]]: disabled,
+ }
+ ),
+ });
+
export const Input = React.forwardRef(
- ({ size = 'medium', error = false, className, ...inputProps }, ref) => {
+ (
+ {
+ inputSize = 'medium',
+ error = false,
+ disabled,
+ icon = null,
+ className,
+ ...inputProps
+ },
+ ref
+ ) => {
+ const [isFocused, setIsFocused] = React.useState(false);
+ const [isPasswordVisible, setIsPasswordVisible] = React.useState(false);
+ const { type } = inputProps;
+ const mergedClassNames = cx(
+ className,
+ styles[baseClass],
+ styles[`${baseClass}--${inputSize}`],
+ {
+ [styles[`${baseClass}--disabled`]]: disabled,
+ [styles[`${baseClass}--focused`]]: isFocused,
+ [styles[`${baseClass}--error`]]: error,
+ }
+ );
+ const iconCustomColor = !disabled
+ ? 'var(--content-default)'
+ : 'var(--content-disabled)';
+ const iconSource = isPasswordVisible ? VisibilityOnIcon : VisibilityOffIcon;
+ const shouldRenderLeftIcon = icon && icon.place === 'left';
+ const shouldRenderRightIcon =
+ icon && type !== 'password' && icon.place === 'right';
+
return (
-
+ {shouldRenderLeftIcon && renderIcon(icon, disabled)}
+ setIsFocused(true)}
+ onBlur={() => setIsFocused(false)}
+ disabled={disabled}
+ type={type && !isPasswordVisible ? type : 'text'}
+ />
+ {shouldRenderRightIcon && renderIcon(icon, disabled)}
+ {type === 'password' && (
+ }
+ onClick={() => setIsPasswordVisible((v) => !v)}
+ className={styles[`${baseClass}__visibility-button`]}
+ />
)}
- type="text"
- ref={ref}
- {...inputProps}
- />
+
);
}
);
diff --git a/packages/react-components/src/components/Picker/Picker.module.scss b/packages/react-components/src/components/Picker/Picker.module.scss
index 9e2373a84..e22efe425 100644
--- a/packages/react-components/src/components/Picker/Picker.module.scss
+++ b/packages/react-components/src/components/Picker/Picker.module.scss
@@ -2,20 +2,20 @@ $base-class: 'picker';
.#{$base-class} {
box-sizing: border-box;
- color: var(--content-default);
display: inline-block;
position: relative;
width: 100%;
+ color: var(--content-default);
&__container {
position: relative;
}
&__label {
+ margin-bottom: 4px;
+ line-height: 20px;
font-size: 14px;
font-weight: 400;
- line-height: 20px;
- margin-bottom: 4px;
&--disabled {
color: var(--content-disabled);
@@ -23,12 +23,12 @@ $base-class: 'picker';
}
&__error {
- color: var(--color-negative-default);
display: flex;
+ margin-top: 4px;
+ line-height: 20px;
+ color: var(--color-negative-default);
font-size: 14px;
font-weight: 400;
- line-height: 20px;
- margin-top: 4px;
&__icon {
margin-right: 5px;
diff --git a/packages/react-components/src/components/Picker/PickerList.module.scss b/packages/react-components/src/components/Picker/PickerList.module.scss
index d15cab725..adabafeea 100644
--- a/packages/react-components/src/components/Picker/PickerList.module.scss
+++ b/packages/react-components/src/components/Picker/PickerList.module.scss
@@ -3,37 +3,37 @@
$base-class: 'picker-list';
.#{$base-class} {
- background-color: var(--surface-basic-default);
- border-radius: 4px;
- box-shadow: 0 6px 20px rgba(66, 77, 87, 0.4);
box-sizing: border-box;
- font-size: 15px;
- font-weight: 400;
- line-height: 22px;
- margin: 0;
- max-height: 242px;
- overflow: scroll;
- padding: 4px 0;
position: absolute;
top: calc(100% + 4px);
- width: 100%;
z-index: $stacking-context-level-dropdown;
+ margin: 0;
+ border-radius: 4px;
+ box-shadow: 0 6px 20px rgb(66 77 87 / 40%);
+ background-color: var(--surface-basic-default);
+ padding: 4px 0;
+ width: 100%;
+ max-height: 242px;
+ overflow: scroll;
+ line-height: 22px;
+ font-size: 15px;
+ font-weight: 400;
&__no-results {
- align-items: center;
display: flex;
- height: 36px;
+ align-items: center;
justify-content: center;
+ height: 36px;
}
&__item {
+ display: flex;
align-items: center;
+ justify-content: space-between;
border: 1px solid transparent;
cursor: pointer;
- display: flex;
- height: 36px;
- justify-content: space-between;
padding: 6px 11px;
+ height: 36px;
&:hover {
background-color: var(--surface-basic-hover);
@@ -57,16 +57,16 @@ $base-class: 'picker-list';
}
&__header {
- align-items: center;
- color: var(--content-subtle);
- cursor: auto;
display: flex;
- font-size: 12px;
- font-weight: 600;
- height: 36px;
+ align-items: center;
justify-content: space-between;
+ cursor: auto;
padding: 7px 12px;
+ height: 36px;
text-transform: uppercase;
+ color: var(--content-subtle);
+ font-size: 12px;
+ font-weight: 600;
}
}
}
diff --git a/packages/react-components/src/components/Picker/Trigger.module.scss b/packages/react-components/src/components/Picker/Trigger.module.scss
index d2321e212..22dc76564 100644
--- a/packages/react-components/src/components/Picker/Trigger.module.scss
+++ b/packages/react-components/src/components/Picker/Trigger.module.scss
@@ -1,20 +1,25 @@
$base-class: 'picker-trigger';
.#{$base-class} {
- align-items: center;
- background-color: var(--surface-basic-default);
- border: 1px solid var(--border-default);
- border-radius: 4px;
box-sizing: border-box;
display: flex;
- font-size: 15px;
- font-weight: 400;
- justify-content: flex-end;
- line-height: 22px;
- padding: 7px 12px;
position: relative;
+ align-items: center;
+ justify-content: flex-end;
transition: border 0.15s ease-in-out;
+ border: 1px solid var(--border-default);
+ border-radius: 4px;
+ background-color: var(--surface-basic-default);
+ padding: 7px 12px;
width: 100%;
+ line-height: 22px;
+ font-size: 15px;
+ font-weight: 400;
+
+ &:hover {
+ border-color: var(--border-hover);
+ cursor: pointer;
+ }
&--compact {
height: 32px;
@@ -36,15 +41,10 @@ $base-class: 'picker-trigger';
}
}
- &:hover {
- border-color: var(--border-hover);
- cursor: pointer;
- }
-
&__controls {
+ display: flex;
align-items: center;
align-self: flex-start;
- display: flex;
&--compact {
height: 18px;
@@ -60,13 +60,13 @@ $base-class: 'picker-trigger';
}
&__clear-icon {
- align-items: center;
- background-color: var(--surface-secondary-subtle);
- border-radius: 50%;
display: flex;
- height: 20px;
+ align-items: center;
justify-content: center;
+ border-radius: 50%;
+ background-color: var(--surface-secondary-subtle);
width: 20px;
+ height: 20px;
}
&__content {
diff --git a/packages/react-components/src/components/Picker/Trigger.tsx b/packages/react-components/src/components/Picker/Trigger.tsx
index 82d7c1d7b..5e3c2e650 100644
--- a/packages/react-components/src/components/Picker/Trigger.tsx
+++ b/packages/react-components/src/components/Picker/Trigger.tsx
@@ -8,11 +8,10 @@ import {
import { Icon } from '../Icon';
import styles from './Trigger.module.scss';
import { KeyCodes } from '../../utils/keyCodes';
+import { Size } from 'utils';
const baseClass = 'picker-trigger';
-export type TriggerSize = 'compact' | 'medium' | 'large';
-
export interface ITriggerProps {
isSearchDisabled: boolean;
isDisabled?: boolean;
@@ -21,7 +20,7 @@ export interface ITriggerProps {
isOpen: boolean;
isRequired?: boolean;
isMultiSelect?: boolean;
- size?: TriggerSize;
+ size?: Size;
onTrigger: (e: React.MouseEvent | KeyboardEvent) => void;
onClear: () => void;
}
diff --git a/packages/react-components/src/components/Picker/TriggerBody.module.scss b/packages/react-components/src/components/Picker/TriggerBody.module.scss
index b5ed05b6a..76a749a5f 100644
--- a/packages/react-components/src/components/Picker/TriggerBody.module.scss
+++ b/packages/react-components/src/components/Picker/TriggerBody.module.scss
@@ -7,15 +7,15 @@ $base-class: 'picker-trigger-body';
justify-content: flex-start;
&__input {
- align-items: center;
- background: none;
- border: 0;
- color: var(--content-default);
display: flex;
flex-grow: 2;
- font-size: 15px;
- height: 22px;
+ align-items: center;
outline: none;
+ border: 0;
+ background: none;
padding: 0;
+ height: 22px;
+ color: var(--content-default);
+ font-size: 15px;
}
}
diff --git a/packages/react-components/src/components/Popover/Popover.module.scss b/packages/react-components/src/components/Popover/Popover.module.scss
index c16247441..225e218fc 100644
--- a/packages/react-components/src/components/Popover/Popover.module.scss
+++ b/packages/react-components/src/components/Popover/Popover.module.scss
@@ -1,13 +1,13 @@
@import '../../utils/StackingContextLevel';
.popover {
- background-color: var(--surface-basic-default);
- border-radius: 4px;
- box-shadow: 0 1px 10px 0 rgba(66, 77, 87, 0.3);
display: none;
- max-width: 336px;
- min-width: 168px;
z-index: $stacking-context-level-popover;
+ border-radius: 4px;
+ box-shadow: var(--shadow-pop-over);
+ background-color: var(--surface-basic-default);
+ min-width: 168px;
+ max-width: 336px;
&:focus {
outline: none;
diff --git a/packages/react-components/src/components/Switch/Switch.module.scss b/packages/react-components/src/components/Switch/Switch.module.scss
index 3417624dd..63d270b3d 100644
--- a/packages/react-components/src/components/Switch/Switch.module.scss
+++ b/packages/react-components/src/components/Switch/Switch.module.scss
@@ -20,8 +20,8 @@ $medium-move: $medium-width - $medium-size;
/* stylelint-disable max-nesting-depth */
.#{$base-class} {
display: inline-block;
- outline: none;
position: relative;
+ outline: none;
&:hover {
$hovered-track: #{$base-class}__track;
@@ -36,26 +36,26 @@ $medium-move: $medium-width - $medium-size;
}
&--large {
- height: $large-height;
width: $large-width;
+ height: $large-height;
}
&--compact {
- height: $compact-height;
width: $compact-width;
+ height: $compact-height;
}
&--medium {
- height: $medium-height;
width: $medium-width;
+ height: $medium-height;
}
&__input {
- cursor: pointer;
- height: 100%;
- margin: 0;
opacity: 0;
+ margin: 0;
+ cursor: pointer;
width: 100%;
+ height: 100%;
&--disabled {
cursor: not-allowed;
@@ -64,28 +64,28 @@ $medium-move: $medium-width - $medium-size;
&__input:focus + .#{$base-class}__container {
.#{$base-class}__track {
- box-shadow: 0 0 1px 2px rgba(var(--color-action-default-rgb), 0.7);
+ box-shadow: 0 0 1px 2px rgb(var(--color-action-default-rgb) 0.7);
}
}
&__container {
- align-items: center;
display: flex;
- height: 100%;
- left: 0;
- pointer-events: none;
position: absolute;
top: 0;
+ left: 0;
+ align-items: center;
width: 100%;
+ height: 100%;
+ pointer-events: none;
}
&__track {
- border-radius: 24px;
flex: 1;
- height: 100%;
transition-duration: $switch-transition-duration;
transition-property: background-color;
transition-timing-function: $switch-transition-timing-function;
+ border-radius: 24px;
+ height: 100%;
&--on#{&}--enabled {
background-color: var(--color-positive-default);
@@ -105,67 +105,67 @@ $medium-move: $medium-width - $medium-size;
}
&__slider {
- align-items: center;
- background: var(--content-white-locked);
- border-radius: 50%;
display: flex;
- justify-content: center;
position: absolute;
top: 50%;
+ align-items: center;
+ justify-content: center;
transform: translateY(-50%);
transition-duration: $switch-transition-duration;
transition-property: left, right;
transition-timing-function: $switch-transition-timing-function;
+ border-radius: 50%;
+ background: var(--content-white-locked);
&--large {
- height: calc(#{$large-size});
width: calc(#{$large-size});
+ height: calc(#{$large-size});
&--on {
- left: calc(#{$large-move} - 3px);
right: 3px;
+ left: calc(#{$large-move} - 3px);
}
&--off {
- left: 3px;
right: calc(#{$large-move} - 3px);
+ left: 3px;
}
}
&--compact {
- height: calc(#{$compact-size});
width: calc(#{$compact-size});
+ height: calc(#{$compact-size});
&--on {
- left: calc(#{$compact-move} - 2px);
right: 2px;
+ left: calc(#{$compact-move} - 2px);
}
&--off {
- left: 2px;
right: calc(#{$compact-move} - 2px);
+ left: 2px;
}
}
&--medium {
- height: calc(#{$medium-size});
width: calc(#{$medium-size});
+ height: calc(#{$medium-size});
&--on {
- left: calc(#{$medium-move} - 3px);
right: 3px;
+ left: calc(#{$medium-move} - 3px);
}
&--off {
- left: 3px;
right: calc(#{$medium-move} - 3px);
+ left: 3px;
}
}
}
&__loader {
- height: 100%;
width: 100%;
+ height: 100%;
&--compact {
padding: 1.5px;
@@ -180,8 +180,8 @@ $medium-move: $medium-width - $medium-size;
}
> div {
- height: 100%;
width: 100%;
+ height: 100%;
}
div:last-child {
diff --git a/packages/react-components/src/components/UploadBar/UploadBar.module.scss b/packages/react-components/src/components/UploadBar/UploadBar.module.scss
index 991843a6e..8b9259265 100644
--- a/packages/react-components/src/components/UploadBar/UploadBar.module.scss
+++ b/packages/react-components/src/components/UploadBar/UploadBar.module.scss
@@ -1,64 +1,64 @@
$base-class: 'upload-bar';
.#{$base-class} {
- background-color: var(--surface-default);
+ box-sizing: border-box;
border: solid 1px var(--border-deault);
border-radius: 8px;
- box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2);
- box-sizing: border-box;
- color: var(--content-default);
- overflow: hidden;
+ box-shadow: 0 2px 6px 0 rgb(0 0 0 / 20%);
+ background-color: var(--surface-default);
padding: 10px;
width: 100%;
+ overflow: hidden;
+ color: var(--content-default);
&--error {
color: var(--color-negative-default);
}
&__wrapper {
- align-content: center;
box-sizing: border-box;
- cursor: pointer;
display: flex;
+ align-content: center;
justify-content: space-between;
+ cursor: pointer;
&__header {
- align-items: center;
display: flex;
- font-size: 15px;
+ align-items: center;
width: 100%;
+ font-size: 15px;
&__icon {
margin-right: 11px;
}
&__title {
- font-size: 14px;
justify-self: flex-start;
- line-height: 1.3;
+ width: 100%;
overflow: hidden;
text-overflow: ellipsis;
+ line-height: 1.3;
white-space: nowrap;
- width: 100%;
+ font-size: 14px;
}
&__collapse-button {
- align-items: center;
- background-color: transparent;
- border: 0;
- border-radius: 4px;
- color: var(--content-default);
- cursor: pointer;
display: flex;
flex: 0 1 auto;
+ align-items: center;
margin: 0;
margin-left: 8px;
+ border: 0;
+ border-radius: 4px;
+ background-color: transparent;
+ cursor: pointer;
padding: 4px;
+ color: var(--content-default);
}
&__actions-container {
- align-items: center;
display: flex;
+ align-items: center;
height: 28px;
}
}
@@ -74,8 +74,8 @@ $base-class: 'upload-bar';
}
&--enter-active {
- max-height: 200px;
transition: max-height 300ms cubic-bezier(0.14, 0, 0, 1);
+ max-height: 200px;
}
&--exit {
@@ -84,27 +84,27 @@ $base-class: 'upload-bar';
&--exit-active,
&--exit-done {
- max-height: 0;
transition: max-height 300ms cubic-bezier(0.14, 0, 0, 1);
+ max-height: 0;
}
&-wrapper {
box-sizing: border-box;
display: flex;
flex-direction: column;
- max-height: inherit;
padding-top: 16px;
width: 100%;
+ max-height: inherit;
}
&__list {
+ padding-right: 20px;
height: 100%;
overflow-y: auto;
- padding-right: 20px;
> div:not(:last-child) {
- margin-bottom: 14px;
margin-top: 5px;
+ margin-bottom: 14px;
}
}
}
diff --git a/packages/react-components/src/foundations/shadow.css b/packages/react-components/src/foundations/shadow.css
index a4d2f269f..cc4824d82 100644
--- a/packages/react-components/src/foundations/shadow.css
+++ b/packages/react-components/src/foundations/shadow.css
@@ -1,5 +1,5 @@
:root {
- --shadow-float: 0 2px 6px rgba(66, 77, 87, 0.4);
- --shadow-pop-over: 0 6px 20px rgba(66, 77, 87, 0.4);
- --shadow-modal: 0 10px 50px rgba(66, 77, 87, 0.4);
+ --shadow-float: 0 2px 6px rgb(66 77 87 / 40%);
+ --shadow-pop-over: 0 6px 20px rgb(66 77 87 / 40%);
+ --shadow-modal: 0 10px 50px rgb(66 77 87 / 40%);
}
diff --git a/packages/react-components/src/index.scss b/packages/react-components/src/index.scss
index 52d14e4f0..3bd9e243c 100644
--- a/packages/react-components/src/index.scss
+++ b/packages/react-components/src/index.scss
@@ -6,8 +6,8 @@
*[class^='lc-'] {
box-sizing: border-box;
- font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, Segoe UI,
- Helvetica Neue, Arial, sans-serif;
+ font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
+ 'Helvetica Neue', Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
diff --git a/packages/react-components/src/index.ts b/packages/react-components/src/index.ts
index 03a4c30ff..6c2389633 100644
--- a/packages/react-components/src/index.ts
+++ b/packages/react-components/src/index.ts
@@ -3,6 +3,7 @@ import './index.scss';
export { DesignToken } from './themes/design-token';
export { SpacingToken } from './foundations/spacing-token';
export { ShadowToken } from './foundations/shadow-token';
+export type { Size } from './utils';
export * from './components/Alert';
export * from './components/Avatar';
diff --git a/packages/react-components/src/stories/components/Spacing.css b/packages/react-components/src/stories/components/Spacing.css
index cd558b604..e9f69eb43 100644
--- a/packages/react-components/src/stories/components/Spacing.css
+++ b/packages/react-components/src/stories/components/Spacing.css
@@ -1,6 +1,6 @@
table {
- border-collapse: collapse;
width: 100%;
+ border-collapse: collapse;
}
table th,
diff --git a/packages/react-components/src/stories/components/SpacingExamples.module.scss b/packages/react-components/src/stories/components/SpacingExamples.module.scss
index eb71278dd..a60ac6c6a 100644
--- a/packages/react-components/src/stories/components/SpacingExamples.module.scss
+++ b/packages/react-components/src/stories/components/SpacingExamples.module.scss
@@ -2,42 +2,55 @@
&--spacing-0 {
padding: 0 var(--spacing-0);
}
+
&--spacing-05 {
padding: 0 var(--spacing-05);
}
+
&--spacing-1 {
padding: 0 var(--spacing-1);
}
+
&--spacing-2 {
padding: 0 var(--spacing-2);
}
+
&--spacing-3 {
padding: 0 var(--spacing-3);
}
+
&--spacing-4 {
padding: 0 var(--spacing-4);
}
+
&--spacing-5 {
padding: 0 var(--spacing-5);
}
+
&--spacing-6 {
padding: 0 var(--spacing-6);
}
+
&--spacing-8 {
padding: 0 var(--spacing-8);
}
+
&--spacing-12 {
padding: 0 var(--spacing-12);
}
+
&--spacing-16 {
padding: 0 var(--spacing-16);
}
+
&--spacing-18 {
padding: 0 var(--spacing-18);
}
+
&--spacing-20 {
padding: 0 var(--spacing-20);
}
+
&--spacing-24 {
padding: 0 var(--spacing-24);
}
diff --git a/packages/react-components/src/utils/constants.ts b/packages/react-components/src/utils/constants.ts
new file mode 100644
index 000000000..51c689c1e
--- /dev/null
+++ b/packages/react-components/src/utils/constants.ts
@@ -0,0 +1 @@
+export type Size = 'compact' | 'medium' | 'large';
diff --git a/packages/react-components/src/utils/index.ts b/packages/react-components/src/utils/index.ts
new file mode 100644
index 000000000..a81284328
--- /dev/null
+++ b/packages/react-components/src/utils/index.ts
@@ -0,0 +1 @@
+export type { Size } from './constants';