diff --git a/.cz-config.js b/.cz-config.js index 1eed4593..da1c2313 100644 --- a/.cz-config.js +++ b/.cz-config.js @@ -2,17 +2,17 @@ const glob = require('glob'); // prettier-ignore const types = [ - { value: "feat", name: "feat", description: "A new feature" }, - { value: "fix", name: "fix", description: "A bug fix" }, - { value: "docs", name: "docs", description: "Documentation only changes" }, - { value: "style", name: "style", description: "Changes that do not affect the meaning of the code", }, - { value: "chore", name: "chore", description: "Changes to the build process or auxiliary tools", }, - { value: "config", name: "config", description: "Changes in configuration files. Add new or remove old." }, + { value: "feat", name: "feat", description: "A new feature" }, + { value: "fix", name: "fix", description: "A bug fix" }, + { value: "docs", name: "docs", description: "Documentation only changes" }, + { value: "style", name: "style", description: "Changes that do not affect the meaning of the code", }, + { value: "chore", name: "chore", description: "Changes to the build process or auxiliary tools", }, + { value: "config", name: "config", description: "Changes in configuration files. Add new or remove old." }, { value: "refactor", name: "refactor", description: "A code change that neither fixes a bug nor adds a feature", }, - { value: "perf", name: "perf", description: "A code change that improves performance" }, - { value: "test", name: "test", description: "Adding missing tests" }, - { value: "revert", name: "revert", description: "Revert to a commit" }, - { value: "wip", name: "wip", description: "Work in progress" }, + { value: "perf", name: "perf", description: "A code change that improves performance" }, + { value: "test", name: "test", description: "Adding missing tests" }, + { value: "revert", name: "revert", description: "Revert to a commit" }, + { value: "wip", name: "wip", description: "Work in progress" }, ] module.exports = { @@ -20,7 +20,7 @@ module.exports = { scopes: [].concat( 'app', globMap('src/*/', (path) => path.replace(/src\//, '')).filter( - exclude(['features', 'ui', 'lib']), + exclude(['features', 'ui', 'lib', 'app']), ), 'features', globMap('src/features/*/', (path) => path.replace('src/', '')), diff --git a/src/api/types.ts b/src/api/types.ts index 41a18760..5047c814 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -1,5 +1,4 @@ import type { EditorValue } from '@cardbox/editor'; -import { UserCard } from '@box/entities/user'; // Экспортируем отдельно, чтобы могли обращаться к типу, не зная, про реализацию (Editor) export type CardContent = EditorValue; @@ -31,7 +30,7 @@ export interface Question { readonly responses: { authors: string[]; count: number; - lastReponseAt: string; + lastResponseAt: string; }; } export interface Answer { diff --git a/src/app/application.tsx b/src/app/application.tsx index 5c947357..798de6cd 100644 --- a/src/app/application.tsx +++ b/src/app/application.tsx @@ -1,5 +1,3 @@ -import './custom-props.css'; - import * as React from 'react'; import styled, { createGlobalStyle } from 'styled-components'; import { Helmet } from 'react-helmet-async'; @@ -8,6 +6,7 @@ import { QueryParamProvider } from 'use-query-params'; import { Route } from 'react-router'; import { Scope } from 'effector/fork'; import { Searchbar } from '@box/features/search-bar'; +import { customProps } from '@box/lib/theme'; import { paths } from '@box/pages/paths'; // FIXME: replace later to usage of entities/viewer import { viewer } from '@box/api/mock/fixtures'; @@ -29,6 +28,8 @@ const Globals = createGlobalStyle` padding: 0; font-family: sans-serif; } + + ${customProps} `; export const Application = ({ root }: Props) => ( @@ -45,8 +46,8 @@ export const Application = ({ root }: Props) => ( - {/* FIXME: - - научиться получать авторизированного пользователя и сюда прокидывать в поле user + {/* FIXME: + - научиться получать авторизированного пользователя и сюда прокидывать в поле user - или прокидывать в виджет напрямую фичи/сущности (Logo, SearchBar, UserAvatar, NewCard) */} ` justify-content: space-between; overflow: hidden; - box-shadow: 0px 3px 9px #faf9fa; + box-shadow: 0 3px 9px #faf9fa; &[data-size='small'] { height: 190px; @@ -98,14 +99,14 @@ const PaperContainerStyled = styled(PaperContainer)<{ &:hover, &:focus { - border-color: var(--wizard300); - background-color: var(--bnw0); + border-color: var(${theme.palette.wizard750}); + background-color: var(${theme.palette.bnw1000}); cursor: pointer; } } &[data-size='large'] { - background: #fff; + background: var(${theme.palette.bnw1000}); min-height: 190px; } `; @@ -159,12 +160,12 @@ const TitleLink = styled(Link)` transition: 0.25s; &:hover { - color: var(--wizard500); + color: var(${theme.palette.wizard500}); } `; const ItemEditorContainer = styled.div` - --editor-color: #62616d; + --editor-color: var(${theme.palette.bnw400}); --editor-font-size: 15px; --editor-line-height: 21px; -webkit-line-clamp: 3; @@ -224,7 +225,7 @@ const AddButtonStyled = styled(button.Icon)<{ 'data-is-card-to-deck-added': boolean; }>` &[data-is-card-to-deck-added='true'] { - background-color: #f7f6ff; + background-color: var(${theme.palette.wizard950}); &:hover { background-color: inherit; @@ -242,7 +243,7 @@ const Header = styled.header` `; const MetaStyled = styled.div` - color: #9b99ac; + color: var(${theme.palette.bnw600}); display: flex; align-items: center; justify-content: space-between; @@ -250,5 +251,5 @@ const MetaStyled = styled.div` const UserLink = styled(Link)` text-decoration: none; - color: #9b99ac; + color: var(${theme.palette.bnw600}); `; diff --git a/src/entities/user/ui/user-card.tsx b/src/entities/user/ui/user-card.tsx index 86ef4303..d9b7a1e1 100644 --- a/src/entities/user/ui/user-card.tsx +++ b/src/entities/user/ui/user-card.tsx @@ -4,6 +4,7 @@ import { Avatar } from '@box/ui/atoms'; import { Link } from 'react-router-dom'; import type { User } from '@box/api'; import { imgLogo } from '@box/shared/assets'; +import { theme } from '@box/lib/theme'; import { getFullName } from '../lib'; @@ -18,6 +19,7 @@ export const UserCard: React.FC = ({ user, getUserHref }) => { const fullName = getFullName(user); const { avatar, work } = user; + const username = `${user.firstName} ${user.lastName}`; return ( @@ -34,10 +36,10 @@ export const UserCard: React.FC = ({ user, getUserHref }) => { const Container = styled.div` align-items: center; - background-color: #fff; - border: 1px solid #e7e5ee; + background-color: var(${theme.palette.bnw1000}); + border: 1px solid var(${theme.palette.bnw850}); border-radius: 6px; - box-shadow: 0px 6px 9px #f6f5f8; + box-shadow: 0 6px 9px var(${theme.palette.bnw950}); display: flex; justify-content: space-between; padding: 1.0625rem 1.3125rem; @@ -51,10 +53,11 @@ const Content = styled.div` const Name = styled.div` font-size: 1.3125rem; line-height: 1.5625rem; + white-space: nowrap; `; const Role = styled.div` - color: #a39bb2; + color: var(${theme.palette.bnw600}); font-size: 0.8125rem; line-height: 1rem; `; @@ -65,6 +68,6 @@ const TitleLink = styled(Link)` transition: 0.25s; &:hover { - color: var(--wizard500); + color: var(${theme.palette.wizard500}); } `; diff --git a/src/entities/user/ui/user-preview.tsx b/src/entities/user/ui/user-preview.tsx index 23215f8f..78e3efd7 100644 --- a/src/entities/user/ui/user-preview.tsx +++ b/src/entities/user/ui/user-preview.tsx @@ -5,6 +5,7 @@ import { Link } from 'react-router-dom'; import type { User } from '@box/api'; import { imgLogo } from '@box/shared/assets'; import { plural } from '@box/lib/plural'; +import { theme } from '@box/lib/theme'; import { useSearchQuery } from '@box/features/search-bar'; interface UserPreviewProps { @@ -36,7 +37,7 @@ export const UserPreview: React.FC = ({ const PaperContainerStyled = styled(PaperContainer)` justify-content: space-between; overflow: hidden; - box-shadow: 0px 3px 9px #faf9fa; + box-shadow: 0 3px 9px #faf9fa; transition: 0.25s; height: 190px; @@ -99,7 +100,7 @@ const Meta = ({ cardsCount }: MetaProps) => { }; const MetaStyled = styled.div` - color: #9b99ac; + color: var(${theme.palette.bnw600}); display: flex; align-items: center; justify-content: space-between; @@ -114,7 +115,7 @@ const ContentStyled = styled.div` } `; const ContentText = styled(Text)` - color: #62616d; + color: var(${theme.palette.bnw400}); overflow: hidden; text-overflow: ellipsis; -webkit-line-clamp: 3; @@ -124,7 +125,7 @@ const ContentText = styled(Text)` const UserLink = styled(Link)` text-decoration: none; - color: #000000; + color: var(${theme.palette.bnw0}); &:hover { color: blue; diff --git a/src/features/card/draft/ui/atoms/reset-changes.tsx b/src/features/card/draft/ui/atoms/reset-changes.tsx index da46a46e..12ebc234 100644 --- a/src/features/card/draft/ui/atoms/reset-changes.tsx +++ b/src/features/card/draft/ui/atoms/reset-changes.tsx @@ -4,8 +4,8 @@ import { useEvent } from 'effector-react/ssr'; import * as model from '../../model'; -// eslint-disable-next-line prettier/prettier -const CANCEL_WARN = 'Are you sure you want to undo the changes? The action is not reversible!'; +const CANCEL_WARN = + 'Are you sure you want to undo the changes? The action is not reversible!'; interface Props { _name: string; diff --git a/src/features/search-bar/molecules/search.tsx b/src/features/search-bar/molecules/search.tsx index 503533cc..e74baf43 100644 --- a/src/features/search-bar/molecules/search.tsx +++ b/src/features/search-bar/molecules/search.tsx @@ -1,6 +1,7 @@ import React from 'react'; import styled from 'styled-components'; import { reflect } from '@effector/reflect/ssr'; +import { theme } from '@box/lib/theme'; import * as model from '../models'; @@ -15,22 +16,21 @@ export const Search = () => { }; const Container = styled.div` - border: 1px solid #e7e5ee; - border-radius: 3px; display: flex; height: 42px; `; const Input = styled.input` border: none; - border-right: 1px solid #e7e5ee; + border-radius: 6px; + background: var(${theme.palette.bnw900}); flex-grow: 1; font-size: 0.9375rem; outline: 0; padding: 0 1.125rem; &::placeholder { - color: #a39bb2; + color: var(${theme.palette.bnw600}); } `; const SearchInput = reflect({ diff --git a/src/features/search-bar/organisms/search-bar.tsx b/src/features/search-bar/organisms/search-bar.tsx index a6500d88..e66f159b 100644 --- a/src/features/search-bar/organisms/search-bar.tsx +++ b/src/features/search-bar/organisms/search-bar.tsx @@ -3,6 +3,7 @@ import React, { useEffect } from 'react'; import { ContentCenteredTemplate, IconLogo, button } from '@box/ui'; import { Link } from 'react-router-dom'; import { SessionPanel } from '@box/entities/session'; +import { theme } from '@box/lib/theme'; import { useEvent } from 'effector-react/ssr'; import * as model from '../models'; @@ -52,8 +53,8 @@ function useSearchQueryChanged() { } const Container = styled.header` - background-color: #fff; - box-shadow: 0 6px 9px #f6f5f8; + background-color: var(${theme.palette.bnw1000}); + box-shadow: 0 6px 9px var(${theme.palette.bnw950}); display: flex; flex-shrink: 0; justify-content: center; @@ -76,6 +77,6 @@ const NewCardLink = styled(Link)` text-decoration: none; button { - color: var(--wizard500); + color: var(${theme.palette.wizard}); } `; diff --git a/src/lib/theme.ts b/src/lib/theme.ts new file mode 100644 index 00000000..d9d43890 --- /dev/null +++ b/src/lib/theme.ts @@ -0,0 +1,172 @@ +import { css } from 'styled-components'; + +// in case of modifying the palette you can only modify this object +// without modifying the rest +const customPropsObject = { + wizard: { + wizard1000: '#fff', + wizard950: '#f6f5ff', + wizard900: '#e8e6fe', + wizard850: '#d6d2fe', + wizard800: '#c0b9fe', + wizard750: '#a59bfd', + wizard700: '#8a7dfc', + wizard650: '#6f5ffc', + wizard600: '#5441fb', + wizard550: '#3923fb', + wizard500: '#1e05fa', + wizard450: '#1a04dc', + wizard400: '#1604be', + wizard350: '#1303a0', + wizard300: '#0f0382', + wizard250: '#0c0264', + wizard200: '#080146', + wizard150: '#05012d', + wizard100: '#030119', + wizard50: '#01000a', + wizard0: '#000', + }, + notice: { + notice1000: '#fff', + notice950: '#fef6f7', + notice900: '#fbe9eb', + notice850: '#f9d8db', + notice800: '#f5c2c7', + notice750: '#f1a7af', + notice700: '#ec8d97', + notice650: '#e8737e', + notice600: '#e45866', + notice550: '#e03e4e', + notice500: '#db2436', + notice450: '#c11f30', + notice400: '#a71b29', + notice350: '#8c1723', + notice300: '#72131c', + notice250: '#580e16', + notice200: '#3d0a0f', + notice150: '#27060a', + notice100: '#160405', + notice50: '#090102', + notice0: '#000', + }, + success: { + success1000: '#fff', + success950: '#f7fdf9', + success900: '#ebfaef', + success850: '#daf6e3', + success800: '#c6f1d3', + success750: '#adebc0', + success700: '#95e4ad', + success650: '#7cde9a', + success600: '#64d887', + success550: '#4bd274', + success500: '#33cc61', + success450: '#2db455', + success400: '#279b4a', + success350: '#21833e', + success300: '#1b6a32', + success250: '#145227', + success200: '#0e391b', + success150: '#092511', + success100: '#05140a', + success50: '#020804', + success0: '#000', + }, + // black and white + bnw: { + bnw1000: '#fff', + bnw950: '#faf9fa', + bnw900: '#f1f1f3', + bnw850: '#e6e6ea', + bnw800: '#d9d8df', + bnw750: '#c8c7d1', + bnw700: '#b8b7c3', + bnw650: '#a8a6b5', + bnw600: '#9795a7', + bnw550: '#878599', + bnw500: '#76748b', + bnw450: '#68667a', + bnw400: '#5a586a', + bnw350: '#4c4a59', + bnw300: '#3e3c48', + bnw250: '#2f2e38', + bnw200: '#212027', + bnw150: '#151519', + bnw100: '#0c0c0e', + bnw50: '#050506', + bnw0: '#000', + }, +}; +function customPropObjectToCss([key, value]: [key: string, value: string]) { + return `--${key}: ${value};`; +} + +export const customProps = css` + :root { + ${Object.keys(customPropsObject).map((subPaletteName) => + Object.entries(customPropsObject[subPaletteName] as [string, string]).map( + customPropObjectToCss, + ), + )} + } +`; + +function customPropsToApi(props: Record) { + const apiKeys = Object.keys(props).map((key) => [key, `--${key}`]); + const subPaletteName = Object.keys(props)[0].replace(/\d+$/, ''); + apiKeys.push([subPaletteName, `--${subPaletteName}500`]); + apiKeys.push([`${subPaletteName}Disabled`, `--${subPaletteName}800`]); + apiKeys.push([`${subPaletteName}Hover`, `--${subPaletteName}400`]); + apiKeys.push([`${subPaletteName}Pressed`, `--${subPaletteName}300`]); + return Object.fromEntries(apiKeys); +} +const wizardApi = customPropsToApi(customPropsObject.wizard); +const bnwApi = customPropsToApi(customPropsObject.bnw); +const noticeApi = customPropsToApi(customPropsObject.notice); +const successApi = customPropsToApi(customPropsObject.success); + +// because of customPropsToApi function (which was created to automate custom +// properties creation) ts cannot output types. in the result we don't have +// autocomplete in the theme usage. to fix it we have to describe types like so. +type WizardKeys = + | keyof typeof customPropsObject.wizard + | 'wizard' + | 'wizardDisabled' + | 'wizardHover' + | 'wizardPressed'; +type BnwKeys = + | keyof typeof customPropsObject.bnw + | 'bnw' + | 'bnwDisabled' + | 'bnwHover' + | 'bnwPressed'; +type NoticeKeys = + | keyof typeof customPropsObject.notice + | 'notice' + | 'noticeDisabled' + | 'noticeHover' + | 'noticePressed'; +type SuccessKeys = + | keyof typeof customPropsObject.success + | 'success' + | 'successDisabled' + | 'successHover' + | 'successPressed'; +type AllKeys = WizardKeys | BnwKeys | NoticeKeys | SuccessKeys; +const palette: Record = { + ...wizardApi, + ...bnwApi, + ...noticeApi, + ...successApi, +}; + +export const theme = { + palette, + shadows: [ + 'none', + `0px 3px 9px var(${palette.bnw950})`, + `0px 6px 9px var(${palette.bnw900})`, + '0 3px 9px #ebebeb', + ], + spacing: (space = 1) => space * 6, +}; diff --git a/src/pages/card/view/index.tsx b/src/pages/card/view/index.tsx index d740db56..c9b4adf9 100644 --- a/src/pages/card/view/index.tsx +++ b/src/pages/card/view/index.tsx @@ -5,6 +5,7 @@ import { ContentCenteredTemplate, button } from '@box/ui'; import { Helmet } from 'react-helmet-async'; import { Link } from 'react-router-dom'; import { UserCard } from '@box/entities/user'; +import { theme } from '@box/lib/theme'; import { useEvent, useStore } from 'effector-react/ssr'; import { useStart, withStart } from '@box/lib/page-routing'; @@ -124,12 +125,13 @@ const LinkBase = styled(Link).attrs(map)<{ disabled?: boolean }>` } `; +// todo: change view for links (according to design from figma) const LinkEdit = styled(LinkBase)` - color: #683aef; + color: var(${theme.palette.wizard550}); `; const ButtonDelete = styled(button.Text)` - color: #ef3a5b; + color: var(${theme.palette.notice500}); width: fit-content; height: auto; padding: 0; diff --git a/src/pages/comments/comments.tsx b/src/pages/comments/comments.tsx index 0553161e..86f4457d 100644 --- a/src/pages/comments/comments.tsx +++ b/src/pages/comments/comments.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; import styled from 'styled-components'; -import { Answer, CommentUser, Question } from '@box/api'; +import { Answer, Question } from '@box/api'; import { Helmet } from 'react-helmet-async'; import { Link } from 'react-router-dom'; import { paths } from '@box/pages/paths'; +import { theme } from '@box/lib/theme'; export const Comments = () => ( <> @@ -28,7 +29,7 @@ export const Comments = () => ( } responses={{ count: 3, - lastReponseAt: 'Last response 8 hours ago', + lastResponseAt: 'Last response 8 hours ago', authors: ['5', '1', '4'], }} > @@ -62,7 +63,7 @@ export const Comments = () => ( } responses={{ count: 6, - lastReponseAt: 'Last response 2 days ago', + lastResponseAt: 'Last response 2 days ago', authors: ['9', '2'], }} /> @@ -79,7 +80,7 @@ export const Comments = () => ( } responses={{ count: 0, - lastReponseAt: '', + lastResponseAt: '', authors: [], }} /> @@ -99,7 +100,7 @@ const Title = styled.h3` line-height: 30px; & > span { - color: #a39bb2; + color: var(${theme.palette.bnw600}); } `; @@ -130,9 +131,9 @@ const Question: React.FC = ({ {topic} {when} - {resolved ? ( + {resolved && ( Question is resolved - ) : null} + )} {text} @@ -142,7 +143,7 @@ const Question: React.FC = ({ ))} {responses.count} responses - {responses.count ? responses.lastReponseAt : 'Write response'} + {responses.count ? responses.lastResponseAt : 'Write response'} {children} @@ -190,7 +191,7 @@ const Topic = styled.h5` font-weight: 500; font-size: 18px; line-height: 36px; - color: #000000; + color: var(${theme.palette.bnw0}); margin: 0; `; @@ -203,7 +204,7 @@ const AuthorImage = styled.img` const When = styled.div` font-size: 15px; line-height: 36px; - color: #a39bb2; + color: var(${theme.palette.bnw600}); `; const Content = styled.div` @@ -215,7 +216,7 @@ const Content = styled.div` const Text = styled.div` font-size: 15px; line-height: 21px; - color: #1a1e23; + color: var(${theme.palette.bnw200}); `; const ResponsesButton = styled.div` @@ -248,11 +249,11 @@ const ResponsesButton = styled.div` display: inline-block; font-size: 15px; line-height: 24px; - color: #a39bb2; + color: var(${theme.palette.bnw600}); margin-left: 9px; &[data-kind='primary'] { - color: #007bff; + color: var(${theme.palette.wizard}); } } `; @@ -265,16 +266,16 @@ const QuestionContainer = styled.div` border-radius: 6px; &:hover { - background-color: #f7f6f9; + background-color: var(${theme.palette.bnw900}); & ${ResponsesButton} { - border-color: #e7e5ee; + border-color: var(${theme.palette.bnw850}); } } `; const Mention = styled.span` - color: #007bff; + color: var(${theme.palette.wizard}); `; const ResolvedChip = styled.div` @@ -283,12 +284,12 @@ const ResolvedChip = styled.div` font-size: 12px; line-height: 22px; padding: 0 9px; - color: #a39bb2; - background-color: #f7f6f9; + color: var(${theme.palette.bnw600}); + background-color: var(${theme.palette.bnw900}); &[data-kind='primary'] { color: white; - background-color: #683aef; + background-color: var(${theme.palette.wizard550}); } `; diff --git a/src/pages/comments/index.tsx b/src/pages/comments/index.tsx index dd8087ec..8542f931 100644 --- a/src/pages/comments/index.tsx +++ b/src/pages/comments/index.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import styled, { createGlobalStyle } from 'styled-components'; +import { theme } from '@box/lib/theme'; import { Comments } from './comments'; @@ -32,8 +33,8 @@ export const CommentsPage = () => { const Globals = createGlobalStyle` body, html { - background-color: #ffffff; - color: #1a1e23; + background-color: var(${theme.palette.bnw1000}); + color: var(${theme.palette.bnw200}); } `; @@ -72,10 +73,10 @@ const Aside = styled.aside` `; const Surface = styled.div` - background-color: #ffffff; - border: 1px solid #e7e5ee; + background-color: var(${theme.palette.bnw1000}); + border: 1px solid var(${theme.palette.bnw850}); box-sizing: border-box; - box-shadow: 0 6px 9px #f6f5f8; + box-shadow: 0 6px 9px var(${theme.palette.bnw950}); border-radius: 6px; display: flex; flex-direction: column; @@ -137,7 +138,7 @@ const Paragraph = styled.p` margin: 0; line-height: 21px; font-size: 15px; - color: #1a1e23; + color: var(${theme.palette.bnw200}); box-sizing: border-box; `; @@ -164,7 +165,7 @@ const DescriberContainer = styled.div` const DescriberTitle = styled.div` font-size: 15px; line-height: 21px; - color: #a39bb2; + color: var(${theme.palette.bnw600}); padding-bottom: 6px; box-sizing: border-box; margin-top: -24px; @@ -179,7 +180,7 @@ const DescriberContent = styled.div` `; const DescriberFooter = styled.div` - background-color: #f7f6f9; + background-color: var(${theme.palette.bnw900}); display: flex; flex-direction: column; align-items: center; diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 141a3c51..98bb5b1d 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -10,6 +10,7 @@ import { button, } from '@box/ui'; import { Helmet } from 'react-helmet-async'; +import { theme } from '@box/lib/theme'; import { useStore } from 'effector-react/ssr'; import { userModel } from '@box/entities/user'; import { withStart } from '@box/lib/page-routing'; @@ -116,7 +117,7 @@ const ToastContainer = styled.div` `; const PrimaryText = styled(Text)` - color: var(--wizard500); + color: var(${theme.palette.wizard500}); `; const Content = styled.div` diff --git a/src/pages/search/page.tsx b/src/pages/search/page.tsx index 3dfde128..acad9686 100644 --- a/src/pages/search/page.tsx +++ b/src/pages/search/page.tsx @@ -8,6 +8,7 @@ import { UserPreviewList, userModel } from '@box/entities/user'; import { historyReplace } from '@box/entities/navigation'; import { reflect } from '@effector/reflect/ssr'; import { searchModel, useSearchQuery } from '@box/features/search-bar'; +import { theme } from '@box/lib/theme'; import { useEvent, useStore } from 'effector-react/ssr'; import * as model from './model'; @@ -83,13 +84,14 @@ const TabStyled = styled(Tab)` margin-right: 1rem; } - color: #9b99ac; + color: var(${theme.palette.bnw600}); transition: color 0.5s; &:hover { + // todo: define colors for hover and others effects color: #4e4d56; } &.react-tabs__tab--selected { - color: #000; + color: var(${theme.palette.bnw0}); } `; diff --git a/src/pages/user/index.tsx b/src/pages/user/index.tsx index 66b8b584..5356b5c3 100644 --- a/src/pages/user/index.tsx +++ b/src/pages/user/index.tsx @@ -9,6 +9,7 @@ import { } from '@box/ui'; import { CardList, cardModel } from '@box/entities/card'; import { imgLogo } from '@box/shared/assets'; +import { theme } from '@box/lib/theme'; import { useStart, withStart } from '@box/lib/page-routing'; import { useStore } from 'effector-react/ssr'; import { userLib, userModel } from '@box/entities/user'; @@ -102,10 +103,10 @@ const Container = styled.div` const UserHeader = styled.div` display: grid; grid-template-columns: repeat(3, 1fr); - background: #ffffff; + background: var(${theme.palette.bnw1000}); - border: 1px solid #eeeef1; - box-shadow: 0px 6px 9px #fbfafb; + border: 1px solid var(${theme.palette.bnw850}); + box-shadow: ${theme.shadows[2]}; border-radius: 6px; padding: 1.5rem 1.875rem; position: relative; @@ -142,9 +143,9 @@ const EditProfile = styled(button.Outline)` `; const StAvatar = styled(Avatar)` - background-color: #ffffff; + background-color: var(${theme.palette.bnw1000}); - border: 1px solid #eeeef1; + border: 1px solid var(${theme.palette.bnw850}); border-radius: 3px; `; @@ -194,11 +195,11 @@ const UserFaceDescription = styled.div` `; const UserFacePosition = styled(UserFaceDescription)` - color: #9b99ac; + color: var(${theme.palette.bnw600}); margin-top: 0; `; const UserLocation = styled(UserFaceDescription)` - color: #9b99ac; + color: var(${theme.palette.bnw600}); margin-top: 0; `; @@ -217,7 +218,7 @@ const SocialStaff = styled.div` `; const SocialStaffTitle = styled.div` - color: #a39bb2; + color: var(${theme.palette.bnw600}); font-size: 0.9375rem; `; @@ -240,13 +241,13 @@ const SocialStaffItem = styled.div` `; const SocialStaffItemText = styled.span` - color: #000; + color: var(${theme.palette.bnw0}); `; const UserCardTitle = styled.div` font-size: 1.125rem; line-height: 1.375rem; - color: #000000; + color: var(${theme.palette.bnw0}); padding: 0; margin-right: 1.875rem; margin-bottom: 20px; @@ -256,7 +257,7 @@ const UserCardTitle = styled.div` `; const SocialLink = styled.a` - ${FontDescription} + ${FontDescription}; display: flex; align-items: center; text-decoration: none; diff --git a/src/pages/user/skeleton.tsx b/src/pages/user/skeleton.tsx index fe80fcb2..201733a5 100644 --- a/src/pages/user/skeleton.tsx +++ b/src/pages/user/skeleton.tsx @@ -7,6 +7,7 @@ import { button, iconUserBg, } from '@box/ui'; +import { theme } from '@box/lib/theme'; import { withStart } from '@box/lib/page-routing'; import * as model from './model'; @@ -74,10 +75,10 @@ const Container = styled.div` const UserHeader = styled.div` display: grid; grid-template-columns: repeat(3, 1fr); - background: #ffffff; + background: var(${theme.palette.bnw1000}); - border: 1px solid #eeeef1; - box-shadow: 0px 6px 9px #fbfafb; + border: 1px solid var(${theme.palette.bnw850}); + box-shadow: ${theme.shadows[2]}; border-radius: 6px; padding: 1.5rem 1.875rem; position: relative; @@ -120,10 +121,10 @@ const shine = keyframes` `; const bgColorSkeleton = css` - background: var(--gray100); + background: var(${theme.palette.bnw950}); box-sizing: border-box; - border: 1px solid #eeeef1; - box-shadow: 0px 3px 9px #fbfafb; + border: 1px solid var(${theme.palette.bnw850}); + box-shadow: ${theme.shadows[1]}; opacity: 0.9; animation: blink 4s infinite ease; @@ -186,11 +187,6 @@ const SocialStaff = styled.div` } `; -const SocialStaffTitle = styled.div` - color: #a39bb2; - font-size: 0.9375rem; -`; - const SocialStaffList = styled.div` display: flex; flex-direction: column; @@ -216,7 +212,7 @@ const SocialStaffItemText = styled.div` `; const StAvatar = styled(Avatar)` - border: 1px solid #eeeef1; + border: 1px solid var(${theme.palette.bnw850}); border-radius: 3px; ${bgColorSkeleton} `; @@ -259,7 +255,7 @@ const EditProfile = styled(button.Outline)` align-items: center; right: 1.875rem; bottom: 1.5rem; - ${bgColorSkeleton} + ${bgColorSkeleton}; width: 160px; `; diff --git a/src/ui/atoms/avatar.tsx b/src/ui/atoms/avatar.tsx index c17d069b..19356db5 100644 --- a/src/ui/atoms/avatar.tsx +++ b/src/ui/atoms/avatar.tsx @@ -1,4 +1,5 @@ import styled, { css } from 'styled-components'; +import { theme } from '@box/lib/theme'; interface Props { src?: string; @@ -10,7 +11,7 @@ const attrs = (props: Props) => ({ }); export const Avatar = styled.div.attrs(attrs)` - background-color: #f4f2f7; + background-color: var(${theme.palette.bnw900}); border-radius: 3px; ${({ src }) => diff --git a/src/ui/atoms/button.tsx b/src/ui/atoms/button.tsx index 8b655b11..adac6e82 100644 --- a/src/ui/atoms/button.tsx +++ b/src/ui/atoms/button.tsx @@ -1,13 +1,14 @@ import styled from 'styled-components'; +import { theme } from '@box/lib/theme'; const Base = styled.button` align-items: center; background-color: transparent; - border: 1px solid var(--wizard500); + border: 1px solid var(${theme.palette.wizard500}); // background-color: #000; // border: 1px solid #000; border-radius: 3px; - color: var(--wizard500); + color: var(${theme.palette.wizard500}); // color: #fff; display: flex; font-size: 1.125rem; @@ -27,9 +28,9 @@ const Base = styled.button` `; const Secondary = styled(Base)` - background-color: #f4f2f7; - border-color: #f4f2f7; - color: #000; + background-color: var(${theme.palette.bnw900}); + border-color: var(${theme.palette.bnw900}); + color: var(${theme.palette.bnw0}); `; const Text = styled(Base)<{ type: 'submit' | 'reset' | 'button' }>` @@ -40,9 +41,9 @@ const Text = styled(Base)<{ type: 'submit' | 'reset' | 'button' }>` `; const Icon = styled(Base)` - background-color: #fff; + background-color: var(${theme.palette.bnw1000}); color: currentColor; - border-color: #eeeef1; + border-color: var(${theme.palette.bnw850}); padding: 0; min-width: 42px; justify-content: center; @@ -58,15 +59,15 @@ const Icon = styled(Base)` `; const Outline = styled(Base)` - background-color: #ffffff; - border: 1px solid #eeeef1; + background-color: var(${theme.palette.bnw1000}); + border: 1px solid var(${theme.palette.bnw850}); border-radius: 0.188rem; - color: #000000; + color: var(${theme.palette.bnw0}); `; const Primary = styled(Base)` - background-color: #4231ff; - color: #ffffff; + background-color: var(${theme.palette.wizard500}); + color: var(${theme.palette.bnw1000}); `; const Group = styled.div` diff --git a/src/ui/atoms/skeleton.tsx b/src/ui/atoms/skeleton.tsx index 6b793455..75c6b9d2 100644 --- a/src/ui/atoms/skeleton.tsx +++ b/src/ui/atoms/skeleton.tsx @@ -1,5 +1,6 @@ import React from 'react'; import styled from 'styled-components'; +import { theme } from '@box/lib/theme'; interface SkeletonProps { // Для базовых кастомизаций (например для высоты) @@ -31,10 +32,10 @@ export const SkeletonGroup: React.FC = ({ const Root = styled.article` height: 220px; - background: var(--gray100); - border: 1px solid #eeeef1; + background: var(${theme.palette.bnw950}); + border: 1px solid var(${theme.palette.bnw850}); box-sizing: border-box; - box-shadow: 0px 3px 9px #fbfafb; + box-shadow: ${theme.shadows[1]}; border-radius: 6px; opacity: 0.5; animation: blink 2s infinite ease; diff --git a/src/ui/atoms/text.tsx b/src/ui/atoms/text.tsx index 14765288..4c01869a 100644 --- a/src/ui/atoms/text.tsx +++ b/src/ui/atoms/text.tsx @@ -38,7 +38,6 @@ export const Text: React.FC = ({ ); function mapTypeToAs(type: TextType) { - /* eslint-disable prettier/prettier */ switch (type) { case TextType.header1: return 'h1'; @@ -57,7 +56,6 @@ function mapTypeToAs(type: TextType) { default: return 'p'; } - /* eslint-enable prettier/prettier */ } const TextStyled = styled.p<{ 'data-type': TextType }>` diff --git a/src/ui/atoms/toast.tsx b/src/ui/atoms/toast.tsx index 0883bbb1..3d36d5b8 100644 --- a/src/ui/atoms/toast.tsx +++ b/src/ui/atoms/toast.tsx @@ -1,5 +1,6 @@ import React from 'react'; import styled from 'styled-components'; +import { theme } from '@box/lib/theme'; interface Props { extra?: React.ReactNode; @@ -17,10 +18,10 @@ export const Toast: React.FC = ({ extra, children }) => { const Root = styled.article` display: flex; - background: var(--wizard100); - border: 1px solid var(--wizard300); + background: var(${theme.palette.wizard950}); + border: 1px solid var(${theme.palette.wizard750}); box-sizing: border-box; - box-shadow: 0px 3px 9px #fbfafb; + box-shadow: ${theme.shadows[1]}; border-radius: 6px; padding: 30px 24px; `; diff --git a/src/ui/molecules/title.tsx b/src/ui/molecules/title.tsx index a9448c3d..609f4693 100644 --- a/src/ui/molecules/title.tsx +++ b/src/ui/molecules/title.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import styled from 'styled-components'; import { button } from '@box/ui'; +import { theme } from '@box/lib/theme'; interface TitleProps { title: string; @@ -19,18 +20,23 @@ const TabTitle: React.FC = ({ setSelectedTab(index); }, [setSelectedTab, index]); return ( - ); }; -const Button = styled(button.Text)<{ active?: boolean }>` +const Button = styled(button.Text)<{ 'data-is-active'?: boolean }>` font-size: 1.125rem; line-height: 1.375rem; - color: ${({ active }) => (active ? '#000000' : '#A39BB2')}; padding: 0; margin-right: 1.875rem; + + color: var(${theme.palette.bnw600}); + &[data-is-active='true'] { + color: var(${theme.palette.bnw0}); + } + & > *:last-child { margin-right: 0; } diff --git a/src/ui/templates/paper-container.ts b/src/ui/templates/paper-container.ts index ea6f227d..0cfb7183 100644 --- a/src/ui/templates/paper-container.ts +++ b/src/ui/templates/paper-container.ts @@ -1,8 +1,9 @@ import styled from 'styled-components'; +import { theme } from '@box/lib/theme'; export const PaperContainer = styled.article` - background-color: var(--bnw100); - border: 1px solid var(--bnw200); + background-color: var(${theme.palette.bnw900}); + border: 1px solid var(${theme.palette.bnw850}); border-radius: 6px; padding: 1.125rem 1.5rem 0.625rem; display: flex;