mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 12:56:41 +07:00
made better tabs (with context)
This commit is contained in:
parent
f63d2d3228
commit
da510e346a
12 changed files with 103 additions and 194 deletions
|
@ -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<any>;
|
||||
}
|
||||
|
||||
const Tab: FC<IProps> = ({ active, onClick, children }) => (
|
||||
<div className={classNames(styles.tab, { [styles.active]: active })} onClick={onClick}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
export { Tab };
|
|
@ -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%);
|
||||
}
|
||||
}
|
|
@ -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<IProps> = ({ children }) => {
|
||||
return <div className={styles.wrap}>{children}</div>;
|
||||
const TabContext = createContext({
|
||||
activeTab: 0,
|
||||
setActiveTab: (activeTab: number) => {},
|
||||
});
|
||||
|
||||
const List: VFC<TabProps> = ({ items }) => {
|
||||
const { activeTab, setActiveTab } = useContext(TabContext);
|
||||
|
||||
return (
|
||||
<div className={styles.tabs}>
|
||||
{items.map((it, index) => (
|
||||
<div
|
||||
className={classNames(styles.tab, { [styles.active]: activeTab === index })}
|
||||
onClick={() => setActiveTab(index)}
|
||||
key={it}
|
||||
>
|
||||
{it}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Content: FC<any> = ({ 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 <TabContext.Provider value={{ activeTab, setActiveTab }}>{children}</TabContext.Provider>;
|
||||
};
|
||||
|
||||
Tabs.List = List;
|
||||
Tabs.Content = Content;
|
||||
|
||||
export { Tabs };
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -76,10 +76,6 @@
|
|||
background: lighten($content_bg, 3%);
|
||||
padding: $gap;
|
||||
border-radius: $radius;
|
||||
|
||||
:global(.input_title) {
|
||||
color: lighten($content_bg, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.search_icon {
|
||||
|
|
|
@ -84,7 +84,7 @@ const InputText: FC<IInputTextProps> = ({
|
|||
</div>
|
||||
|
||||
{title && (
|
||||
<div className={classNames(styles.title, 'input_title')}>
|
||||
<div className={classNames(styles.title)}>
|
||||
<span>{title}</span>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -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<ITextInputProps> = ({
|
||||
type = 'text',
|
||||
placeholder = '',
|
||||
label,
|
||||
onChange = () => {},
|
||||
value = '',
|
||||
}) => (
|
||||
<div
|
||||
className={styles.wrapper}
|
||||
>
|
||||
<div className={styles.container}>
|
||||
{
|
||||
label
|
||||
&& <div className={styles.label}>{label}</div>
|
||||
}
|
||||
<input
|
||||
placeholder={placeholder}
|
||||
className={styles.input}
|
||||
type={type}
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
|
@ -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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue