Skip to content

Commit

Permalink
feat: redesign input, button
Browse files Browse the repository at this point in the history
  • Loading branch information
TomatoVan committed Apr 22, 2024
1 parent f1343ae commit a8969f5
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 77 deletions.
5 changes: 5 additions & 0 deletions extractedTranslations/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
"Article ratings coming soon!": "",
"Articles app": "",
"Articles not found": "",
"Ascending": "",
"Back to list": "",
"Cancel": "",
"Choose country": "",
"Choose currency": "",
"Comments": "",
"Comments is loading": "",
"Create new article": "",
"Creation date": "",
"Descending": "",
"Economics": "",
"Edit": "",
"Enter ": "",
Expand All @@ -28,6 +31,7 @@
"Incorrect country": "",
"Incorrect user data": "",
"Leave your feedback on the article, it will help improve the quality": "",
"Name": "",
"No data": "",
"PROFILE PAGE": "",
"Profile": "",
Expand All @@ -49,6 +53,7 @@
"Sorting by": "",
"Thanks for review!": "",
"Try to reload page": "",
"Views": "",
"Welcome to the articles page!": "",
"You don`t have access to this page!": "",
"Your name": "",
Expand Down
10 changes: 5 additions & 5 deletions src/features/ArtilcleSortSelector/ui/ArticleSortSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ export const ArticleSortSelector = memo((props: ArticleSortSelectorProps) => {
() => [
{
value: 'asc',
content: t('ascending'),
content: t('Ascending'),
},
{
value: 'desc',
content: t('descending'),
content: t('Descending'),
},
],
[t],
Expand All @@ -40,15 +40,15 @@ export const ArticleSortSelector = memo((props: ArticleSortSelectorProps) => {
() => [
{
value: ArticleSortField.CREATED,
content: t('creation date'),
content: t('Creation date'),
},
{
value: ArticleSortField.TITLE,
content: t('name'),
content: t('Name'),
},
{
value: ArticleSortField.VIEWS,
content: t('views'),
content: t('Views'),
},
],
[t],
Expand Down
3 changes: 3 additions & 0 deletions src/shared/assets/icons/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 22 additions & 2 deletions src/shared/ui/redesigned/Button/Button.module.scss
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
.Button {
cursor: pointer;
color: var(--text-redesigned);
padding: 6px 15px;
padding: 8px 16px;
display: flex;
align-items: center;

.addonRight svg,
.addonLeft svg {
color: var(--hint-redesigned);
}

&:hover {
color: var(--accent-redesigned);

.addonLeft svg,
.addonRight svg {
color: var(--accent-redesigned);
}
}
}

.withAddon {
padding: 0 16px;
}

.addonLeft,
.addonRight {
display: flex;
}

.clear {
padding: 0;
border: none;
Expand All @@ -19,7 +40,6 @@
background: var(--light-bg-redesigned);
border: none;
outline: none;
padding: 8px 16px;
border-radius: 34px;
}

Expand Down
11 changes: 10 additions & 1 deletion src/shared/ui/redesigned/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ButtonHTMLAttributes, memo, ReactNode } from 'react';
import React, { ButtonHTMLAttributes, memo, ReactNode } from 'react';
import { classNames, Mods } from '@/shared/lib/classNames/classNames';
import cls from './Button.module.scss';

Expand All @@ -14,6 +14,8 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
isDisabled?: boolean;
children?: ReactNode;
fullWidth?: boolean;
addonLeft?: ReactNode;
addonRight?: ReactNode;
}

export const Button = memo((props: ButtonProps) => {
Expand All @@ -25,13 +27,18 @@ export const Button = memo((props: ButtonProps) => {
isDisabled,
size = 'm',
fullWidth,
addonLeft,
addonRight,
...otherProps
} = props;

const mods: Mods = {
[cls.square]: square,
[cls.isDisabled]: isDisabled,
[cls.fullWidth]: fullWidth,
[cls.withAddonLeft]: Boolean(addonLeft),
[cls.withAddonRight]: Boolean(addonRight),
[cls.withAddon]: Boolean(addonLeft) || Boolean(addonRight),
};

const additional = [className, cls[variant], cls[size]];
Expand All @@ -43,7 +50,9 @@ export const Button = memo((props: ButtonProps) => {
disabled={isDisabled}
{...otherProps}
>
<div className={cls.addonLeft}>{addonLeft}</div>
{children}
<div className={cls.addonRight}>{addonRight}</div>
</button>
);
});
66 changes: 30 additions & 36 deletions src/shared/ui/redesigned/Input/Input.module.scss
Original file line number Diff line number Diff line change
@@ -1,53 +1,47 @@
.InputWrapper {
display: flex;
align-items: center;
border-radius: 48px;
padding: 8px 16px;
border: 2px solid var(--icon-redesigned);
height: 32px;
width: 100%;
}

.placeholder {
margin-right: 5px;
.addonLeft,
.addonRight {
display: flex;
}

.input {
background: transparent;
border: none;
outline: none;
width: 100%;
color: transparent;
text-shadow: 0 0 0 var(--primary-color);

&:focus {
outline: none;
}
.withAddonLeft {
padding-left: 8px;
}

.caretWrapper {
flex-grow: 1;
position: relative;
.withAddonRight {
padding-right: 8px;
}

.caret {
height: 3px;
width: 9px;
background: var(--primary-color);
bottom: 0;
left: 0;
position: absolute;
animation: blink 0.7s forwards infinite;
}
.focused {
border: 2px solid var(--accent-redesigned);

.readonly {
opacity: 0.7;
.addonLeft svg,
.addonRight svg {
color: var(--accent-redesigned);
}
}

@keyframes blink {
0% {
opacity: 0;
}
.input {
border: none;
outline: none;
width: 100%;
color: var(--text-redesigned);
background: none;

50% {
opacity: 0.01;
&::placeholder {
color: var(--hint-redesigned);
}
}

100% {
opacity: 1;
}
.readonly {
opacity: 0.7;
}
55 changes: 23 additions & 32 deletions src/shared/ui/redesigned/Input/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {
InputHTMLAttributes,
memo,
ReactNode,
useEffect,
useRef,
useState,
Expand All @@ -19,6 +20,8 @@ interface InputProps extends HTMLInputProps {
onChange?: (value: string) => void;
autofocus?: boolean;
readonly?: boolean;
addonLeft?: ReactNode;
addonRight?: ReactNode;
}

export const Input = memo((props: InputProps) => {
Expand All @@ -30,13 +33,12 @@ export const Input = memo((props: InputProps) => {
placeholder,
autofocus,
readonly,
addonLeft,
addonRight,
...otherProps
} = props;
const ref = useRef<HTMLInputElement>(null);
const [isFocused, setIsFocused] = useState(false);
const [caretPosition, setCaretPosition] = useState(0);

const isCaretVisible = isFocused && !readonly;

useEffect(() => {
if (autofocus) {
Expand All @@ -47,7 +49,6 @@ export const Input = memo((props: InputProps) => {

const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
onChange?.(e.target.value);
setCaretPosition(e.target.value.length);
};

const onBlur = () => {
Expand All @@ -58,39 +59,29 @@ export const Input = memo((props: InputProps) => {
setIsFocused(true);
};

const onSelect = (e: any) => {
setCaretPosition(e?.target?.selectionStart || 0);
};

const mods: Mods = {
[cls.readonly]: readonly,
[cls.focused]: isFocused,
[cls.withAddonLeft]: Boolean(addonLeft),
[cls.withAddonRight]: Boolean(addonRight),
};

return (
<div className={classNames(cls.InputWrapper, {}, [className])}>
{placeholder && (
<div className={cls.placeholder}>{`${placeholder}>`}</div>
)}
<div className={cls.caretWrapper}>
<input
ref={ref}
type={type}
value={value}
onChange={onChangeHandler}
className={cls.input}
onFocus={onFocus}
onBlur={onBlur}
onSelect={onSelect}
readOnly={readonly}
{...otherProps}
/>
{isCaretVisible && (
<span
className={cls.caret}
style={{ left: `${caretPosition * 9}px` }}
/>
)}
</div>
<div className={classNames(cls.InputWrapper, mods, [className])}>
<div className={cls.addonLeft}>{addonLeft}</div>
<input
ref={ref}
type={type}
value={value}
onChange={onChangeHandler}
className={cls.input}
onFocus={onFocus}
onBlur={onBlur}
readOnly={readonly}
placeholder={placeholder}
{...otherProps}
/>
<div className={cls.addonRight}>{addonRight}</div>
</div>
);
});
8 changes: 7 additions & 1 deletion src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import cls from './ListBox.module.scss';
import { mapDirectionClass } from '../../styles/consts';
import popupCls from '../../styles/popup.module.scss';
import { DropDownDirection } from '@/shared/types/ui';
import ArrowIcon from '@/shared/assets/icons/arrow-bottom.svg';
import { Icon } from '../../../Icon';

export interface ListBoxItem<T extends string> {
value: string;
Expand Down Expand Up @@ -58,7 +60,11 @@ export function ListBox<T extends string>(props: ListBoxProps<T>) {
onChange={onChange}
>
<HListBox.Button className={cls.trigger}>
<Button variant="filled" disabled={readonly}>
<Button
variant="filled"
disabled={readonly}
addonRight={<Icon Svg={ArrowIcon} />}
>
{selectedItem?.content ?? defaultValue}
</Button>
</HListBox.Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { ArticleSortField, ArticleType } from '@/entities/Article';
import { SortOrder } from '@/shared/types/sort';
import { ArticleSortSelector } from '@/features/ArtilcleSortSelector';
import { Input } from '@/shared/ui/redesigned/Input';
import SearchIcon from '@/shared/assets/icons/search.svg';
import { Icon } from '@/shared/ui/redesigned/Icon';

interface ArticlesFiltersProps {
className?: string;
Expand Down Expand Up @@ -46,6 +48,7 @@ export const ArticlesFilters = memo((props: ArticlesFiltersProps) => {
onChange={onChangeSearch}
value={search}
placeholder={t('Search')}
addonLeft={<Icon Svg={SearchIcon} />}
/>
<ArticleTypeTabs
value={type}
Expand Down

0 comments on commit a8969f5

Please sign in to comment.