From da510e346aee0c2c4ff39dd49205788e4ee66231 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Sun, 26 Dec 2021 11:25:34 +0700 Subject: [PATCH] made better tabs (with context) --- src/components/dialogs/Tab/index.tsx | 16 ----- src/components/dialogs/Tab/styles.module.scss | 20 ------- src/components/dialogs/Tabs/index.tsx | 49 ++++++++++++++-- .../dialogs/Tabs/styles.module.scss | 26 ++++++++- .../flow/FlowStamp/styles.module.scss | 4 -- src/components/input/InputText/index.tsx | 2 +- src/components/input/TextInput/index.tsx | 37 ------------ .../input/TextInput/styles.module.scss | 58 ------------------- .../dialogs/ProfileDialog/index.tsx | 55 +++++++++--------- src/containers/profile/ProfileTabs/index.tsx | 25 +------- src/layouts/BorisLayout/index.tsx | 2 + src/styles/common/inputs.module.scss | 3 +- 12 files changed, 103 insertions(+), 194 deletions(-) delete mode 100644 src/components/dialogs/Tab/index.tsx delete mode 100644 src/components/dialogs/Tab/styles.module.scss delete mode 100644 src/components/input/TextInput/index.tsx delete mode 100644 src/components/input/TextInput/styles.module.scss diff --git a/src/components/dialogs/Tab/index.tsx b/src/components/dialogs/Tab/index.tsx deleted file mode 100644 index 20b49d77..00000000 --- a/src/components/dialogs/Tab/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React, { FC, MouseEventHandler } from 'react'; -import classNames from 'classnames'; -import styles from './styles.module.scss'; - -interface IProps { - active?: boolean; - onClick?: MouseEventHandler; -} - -const Tab: FC = ({ active, onClick, children }) => ( -
- {children} -
-); - -export { Tab }; diff --git a/src/components/dialogs/Tab/styles.module.scss b/src/components/dialogs/Tab/styles.module.scss deleted file mode 100644 index be3d83e4..00000000 --- a/src/components/dialogs/Tab/styles.module.scss +++ /dev/null @@ -1,20 +0,0 @@ -@import "src/styles/variables"; - -.tab { - @include outer_shadow(); - - padding: $gap; - margin-right: $gap; - border-radius: $radius $radius 0 0; - font: $font_14_semibold; - text-transform: uppercase; - cursor: pointer; - background-color: $content_bg; - color: white; - text-decoration: none; - border: none; - - &.active { - background: lighten($content_bg, 4%); - } -} diff --git a/src/components/dialogs/Tabs/index.tsx b/src/components/dialogs/Tabs/index.tsx index f7ca42fd..80c7e0d2 100644 --- a/src/components/dialogs/Tabs/index.tsx +++ b/src/components/dialogs/Tabs/index.tsx @@ -1,12 +1,51 @@ -import React, { FC, useCallback } from 'react'; +import React, { createContext, FC, VFC, useContext, useState } from 'react'; import styles from './styles.module.scss'; import classNames from 'classnames'; -import { IAuthState } from '~/redux/auth/types'; -interface IProps {} +interface TabProps { + items: string[]; +} -const Tabs: FC = ({ children }) => { - return
{children}
; +const TabContext = createContext({ + activeTab: 0, + setActiveTab: (activeTab: number) => {}, +}); + +const List: VFC = ({ items }) => { + const { activeTab, setActiveTab } = useContext(TabContext); + + return ( +
+ {items.map((it, index) => ( +
setActiveTab(index)} + key={it} + > + {it} +
+ ))} +
+ ); }; +const Content: FC = ({ children }) => { + const { activeTab } = useContext(TabContext); + + if (!Array.isArray(children) && activeTab > 0) { + return null; + } + + return Array.isArray(children) ? children[activeTab] : children; +}; + +const Tabs = function({ children }) { + const [activeTab, setActiveTab] = useState(0); + + return {children}; +}; + +Tabs.List = List; +Tabs.Content = Content; + export { Tabs }; diff --git a/src/components/dialogs/Tabs/styles.module.scss b/src/components/dialogs/Tabs/styles.module.scss index 3e915328..8fb26f9f 100644 --- a/src/components/dialogs/Tabs/styles.module.scss +++ b/src/components/dialogs/Tabs/styles.module.scss @@ -1,4 +1,4 @@ -@import "src/styles/variables"; +@import "~/styles/variables"; .wrap { display: flex; @@ -6,3 +6,27 @@ justify-content: flex-start; padding: 0 $gap / 2; } + +.tab { + @include outer_shadow(); + + padding: $gap; + margin-right: $gap; + border-radius: $radius $radius 0 0; + font: $font_14_semibold; + text-transform: uppercase; + cursor: pointer; + background-color: $content_bg; + color: white; + text-decoration: none; + border: none; + + &.active { + background: lighten($content_bg, 4%); + } +} + +.tabs { + display: flex; + flex-direction: row; +} \ No newline at end of file diff --git a/src/components/flow/FlowStamp/styles.module.scss b/src/components/flow/FlowStamp/styles.module.scss index 5ec4a613..ece6125f 100644 --- a/src/components/flow/FlowStamp/styles.module.scss +++ b/src/components/flow/FlowStamp/styles.module.scss @@ -76,10 +76,6 @@ background: lighten($content_bg, 3%); padding: $gap; border-radius: $radius; - - :global(.input_title) { - color: lighten($content_bg, 10%); - } } .search_icon { diff --git a/src/components/input/InputText/index.tsx b/src/components/input/InputText/index.tsx index 1d4f4153..737b1485 100644 --- a/src/components/input/InputText/index.tsx +++ b/src/components/input/InputText/index.tsx @@ -84,7 +84,7 @@ const InputText: FC = ({ {title && ( -
+
{title}
)} diff --git a/src/components/input/TextInput/index.tsx b/src/components/input/TextInput/index.tsx deleted file mode 100644 index 187cba81..00000000 --- a/src/components/input/TextInput/index.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react'; -import styles from './styles.module.scss'; - -interface ITextInputProps { - type?: 'text' | 'password'; - placeholder?: string; - label?: string; - value?: string; - - onChange: React.ChangeEventHandler; -} - -export const TextInput: React.FunctionComponent = ({ - type = 'text', - placeholder = '', - label, - onChange = () => {}, - value = '', -}) => ( -
-
- { - label - &&
{label}
- } - -
-
-); diff --git a/src/components/input/TextInput/styles.module.scss b/src/components/input/TextInput/styles.module.scss deleted file mode 100644 index cddf3233..00000000 --- a/src/components/input/TextInput/styles.module.scss +++ /dev/null @@ -1,58 +0,0 @@ -@import "src/styles/variables"; - -.wrapper { - height: $input_height; - display: flex; - flex-direction: column; - align-items: flex-start; - position: relative; - flex: 1; -} - -.label { - // background: transparentize(black, 0.8); - font: $font_14_medium; - // color: transparentize(white, 0.5); - text-transform: uppercase; - padding: 2px $gap; - display: flex; - align-items: center; - justify-content: flex-start; - border-radius: $radius 0 0 $radius; - //@include input_shadow(); - - padding: 0 5px; - position: absolute; - bottom: $input_height - 3px; - font: $font_10_semibold; - background-color: white; - color: transparentize(white, 0.5); - border-radius: $radius; - left: 6px; - background: $content_bg; - height: 10px; -} - -.container { - height: $input_height; - background: $input_bg_color; - border-radius: $input_radius; - flex-direction: row; - flex: 1 0; - display: flex; - align-self: stretch; - align-items: stretch; - justify-content: center; - @include input_shadow(); -} - -.input { - outline: none; - background: transparent; - flex: 1; - border: none; - font-size: inherit; - color: white; - padding: 0 $gap; - box-sizing: border-box; -} diff --git a/src/containers/dialogs/ProfileDialog/index.tsx b/src/containers/dialogs/ProfileDialog/index.tsx index 23e247b9..e013b0cd 100644 --- a/src/containers/dialogs/ProfileDialog/index.tsx +++ b/src/containers/dialogs/ProfileDialog/index.tsx @@ -4,22 +4,16 @@ import { ProfileInfo } from '~/containers/profile/ProfileInfo'; import { IDialogProps } from '~/redux/types'; import { connect } from 'react-redux'; import { selectAuthProfile, selectAuthUser } from '~/redux/auth/selectors'; -import { ProfileMessages } from '~/containers/profile/ProfileMessages'; -import { ProfileDescription } from '~/components/profile/ProfileDescription'; import * as AUTH_ACTIONS from '~/redux/auth/actions'; import { IAuthState } from '~/redux/auth/types'; import { pick } from 'ramda'; import { CoverBackdrop } from '~/components/containers/CoverBackdrop'; +import { MessageForm } from '~/components/profile/MessageForm'; +import { Tabs } from '~/components/dialogs/Tabs'; +import { ProfileDescription } from '~/components/profile/ProfileDescription'; +import { ProfileMessages } from '~/containers/profile/ProfileMessages'; import { ProfileSettings } from '~/components/profile/ProfileSettings'; import { ProfileAccounts } from '~/components/profile/ProfileAccounts'; -import { MessageForm } from '~/components/profile/MessageForm'; - -const TAB_CONTENT = { - profile: , - messages: , - settings: , - accounts: , -}; const mapStateToProps = state => ({ profile: selectAuthProfile(state), @@ -52,23 +46,30 @@ const ProfileDialogUnconnected: FC = ({ ]); return ( - - } - footer={PROFILE_FOOTERS[tab]} - backdrop={} - onClose={onRequestClose} - > - {TAB_CONTENT[tab] || null} - + + + } + footer={PROFILE_FOOTERS[tab]} + backdrop={} + onClose={onRequestClose} + > + + + + + + + + ); }; diff --git a/src/containers/profile/ProfileTabs/index.tsx b/src/containers/profile/ProfileTabs/index.tsx index 1f893442..cdc15986 100644 --- a/src/containers/profile/ProfileTabs/index.tsx +++ b/src/containers/profile/ProfileTabs/index.tsx @@ -1,9 +1,7 @@ import React, { FC, useCallback } from 'react'; import styles from './styles.module.scss'; -import classNames from 'classnames'; import { IAuthState } from '~/redux/auth/types'; import { Tabs } from '~/components/dialogs/Tabs'; -import { Tab } from '~/components/dialogs/Tab'; interface IProps { tab: string; @@ -12,30 +10,11 @@ interface IProps { } const ProfileTabs: FC = ({ tab, is_own, setTab }) => { - const changeTab = useCallback( - (tab: IAuthState['profile']['tab']) => () => { - if (!setTab) return; - setTab(tab); - }, - [setTab] - ); + const items = ['Профиль', 'Сообщения', ...(is_own ? ['Настройки'] : [])]; return (
- - - Профиль - - - - Сообщения - - {is_own && ( - - Настройки - - )} - +
); }; diff --git a/src/layouts/BorisLayout/index.tsx b/src/layouts/BorisLayout/index.tsx index 7e0dc9c9..cb4df796 100644 --- a/src/layouts/BorisLayout/index.tsx +++ b/src/layouts/BorisLayout/index.tsx @@ -10,6 +10,8 @@ import { SidebarRouter } from '~/containers/main/SidebarRouter'; import { BorisSidebar } from '~/components/boris/BorisSidebar'; import { useUserContext } from '~/utils/context/UserContextProvider'; import { BorisUsageStats } from '~/redux/boris/reducer'; +import { Tabs } from '~/components/dialogs/Tabs'; +import { Superpower } from '~/components/boris/Superpower'; type IProps = { title: string; diff --git a/src/styles/common/inputs.module.scss b/src/styles/common/inputs.module.scss index 22c566be..17fa3754 100644 --- a/src/styles/common/inputs.module.scss +++ b/src/styles/common/inputs.module.scss @@ -4,7 +4,6 @@ position: relative; min-height: 40px; border-radius: $input_radius; - //box-shadow: $input_shadow; flex: 1; display: flex; opacity: 1; @@ -274,7 +273,7 @@ transition: top 0.25s, bottom 0.25s, font 0.25s, color 0.25s; pointer-events: none; touch-action: none; - color: transparentize(white, 0.5); + color: lighten($content_bg, 10%); text-transform: capitalize; background: $input_bg_color;