1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-25 04:46:40 +07:00

added tag input field

This commit is contained in:
Fedor Katurov 2019-10-09 12:49:08 +07:00
parent f8b3adc4e2
commit df1c11a308
6 changed files with 78 additions and 25 deletions

View file

@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React, { FC, ReactElement, ChangeEvent, ChangeEventHandler } from 'react';
import * as styles from './styles.scss'; import * as styles from './styles.scss';
import { ITag } from '~/redux/types'; import { ITag } from '~/redux/types';
@ -9,6 +9,7 @@ interface IProps {
feature?: ITag['feature']; feature?: ITag['feature'];
is_hoverable?: boolean; is_hoverable?: boolean;
onInput?: ChangeEventHandler<HTMLInputElement>;
} }
const Tag: FC<IProps> = ({ const Tag: FC<IProps> = ({
@ -16,11 +17,25 @@ const Tag: FC<IProps> = ({
feature, feature,
is_hoverable, is_hoverable,
onInput,
}) => ( }) => (
<div className={classNames(styles.tag, feature, { is_hoverable })}> <div className={classNames(styles.tag, feature, { is_hoverable, input: !!onInput })}>
<div className={styles.hole} /> <div className={styles.hole} />
<div className={styles.title}>{title}</div> <div className={styles.title}>{title}</div>
{onInput && (
<input
type="text"
value={title}
onChange={onInput}
size={1}
placeholder="Добавить"
maxLength={24}
/>
)}
</div> </div>
); );
export { Tag }; export { Tag };
// </div>

View file

@ -6,11 +6,12 @@
align-items: center; align-items: center;
justify-content: stretch; justify-content: stretch;
border-radius: ($tag_height / 2) 3px 3px ($tag_height / 2); border-radius: ($tag_height / 2) 3px 3px ($tag_height / 2);
font: $font_12_semibold; font: $font_14_semibold;
align-self: flex-start; align-self: flex-start;
padding: 0 8px 0 0; padding: 0 8px 0 0;
box-shadow: $shadow_depth_2; box-shadow: $shadow_depth_2;
margin: ($gap / 2) $gap ($gap / 2) 0; margin: ($gap / 2) $gap ($gap / 2) 0;
position: relative;
&:global(.is_hoverable) { &:global(.is_hoverable) {
cursor: pointer; cursor: pointer;
@ -37,9 +38,35 @@
background: transparentize(black, 0.7); background: transparentize(black, 0.7);
box-shadow: none; box-shadow: none;
color: transparentize(white, 0.6); color: transparentize(white, 0.6);
font: $font_12_medium; font: $font_14_medium;
.hole::after { background: transparentize(white, 0.98); } .hole::after {
background: transparentize(white, 0.98);
}
}
&:global(.input) {
color: transparent !important;
min-width: 100px;
}
input {
background: none;
border: none;
color: white;
outline: none;
display: inline-flex;
position: absolute;
font: inherit;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
padding-left: 23px;
padding-right: 5px;
box-sizing: border-box;
} }
} }
@ -50,6 +77,7 @@
margin-right: 3px; margin-right: 3px;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex: 0 0 22px;
&::after { &::after {
content: ' '; content: ' ';
@ -63,4 +91,7 @@
.title { .title {
white-space: nowrap; white-space: nowrap;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
} }

View file

@ -1,25 +1,31 @@
import React, { FC, HTMLAttributes } from 'react'; import React, { FC, HTMLAttributes, useState, useCallback, ChangeEvent } from 'react';
import { TagField } from '~/components/containers/TagField'; import { TagField } from '~/components/containers/TagField';
import { ITag } from '~/redux/types'; import { ITag } from '~/redux/types';
import { Tag } from '~/components/node/Tag'; import { Tag } from '~/components/node/Tag';
type IProps = HTMLAttributes<HTMLDivElement> & { type IProps = HTMLAttributes<HTMLDivElement> & {
tags: ITag[]; tags: ITag[];
} is_editable?: boolean;
onChange?: (tags: string[]) => void;
};
export const Tags: FC<IProps> = ({ export const Tags: FC<IProps> = ({ tags, is_editable, onChange, ...props }) => {
tags, const [input, setInput] = useState('asdasdasdasdasdasdasdasdasdasdasasdasdasdasdasdasdasda');
...props
}) => ( const onInput = useCallback(
({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
setInput(value);
},
[setInput]
);
return (
<TagField {...props}> <TagField {...props}>
{ {tags.map(tag => (
tags.map(tag => ( <Tag key={tag.title} title={tag.title} feature={tag.feature} />
<Tag ))}
key={tag.title}
title={tag.title} <Tag title={input} onInput={onInput} />
feature={tag.feature}
/>
))
}
</TagField> </TagField>
); );
};

View file

@ -63,7 +63,7 @@ const NodeLayoutUnconnected: FC<IProps> = ({
</Group> </Group>
<div className={styles.panel}> <div className={styles.panel}>
<Group style={{ flex: 1 }}> <Group style={{ flex: 1, minWidth: 0 }}>
<NodeTags /> <NodeTags />
<NodeRelated title="First album" /> <NodeRelated title="First album" />

View file

@ -14,6 +14,7 @@
align-items: flex-start; align-items: flex-start;
justify-content: flex-start; justify-content: flex-start;
padding-left: $gap / 2; padding-left: $gap / 2;
min-width: 0;
@include tablet { @include tablet {
padding-left: 0; padding-left: 0;

View file

@ -5,7 +5,7 @@ import { IUser } from './auth/types';
export interface ITag { export interface ITag {
title: string; title: string;
feature?: 'red' | 'blue' | 'green' | 'olive' | 'black'; feature?: 'red' | 'blue' | 'green' | 'olive' | 'black' | 'input';
} }
export type IInputTextProps = DetailedHTMLProps< export type IInputTextProps = DetailedHTMLProps<