1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-05-03 16:46:41 +07:00

several bug fixes

This commit is contained in:
Fedor Katurov 2019-11-15 13:36:13 +07:00
parent f23b9166e1
commit 11348aa411
13 changed files with 281 additions and 110 deletions
src
components
node
NodeImageSlideBlock
NodeNoComments
NodePanel
NodePanelInner
NodeRelated
NodeTags
Tags
placeholders/Placeholder
containers/node/NodeLayout
styles

View file

@ -228,12 +228,14 @@ const NodeImageSlideBlock: FC<IProps> = ({
</div> </div>
)} )}
<ImageSwitcher {!is_loading && (
total={images.length} <ImageSwitcher
current={current} total={images.length}
onChange={changeCurrent} current={current}
loaded={loaded} onChange={changeCurrent}
/> loaded={loaded}
/>
)}
<div <div
className={styles.image_container} className={styles.image_container}
@ -253,7 +255,7 @@ const NodeImageSlideBlock: FC<IProps> = ({
is_active: index === current && loaded[index] is_active: index === current && loaded[index]
})} })}
ref={setRef(index)} ref={setRef(index)}
key={file.id} key={node.updated_at + file.id}
> >
<img <img
className={styles.image} className={styles.image}

View file

@ -1,10 +1,10 @@
import React, { FC } from 'react'; import React, { FC } from "react";
import * as styles from './styles.scss'; import * as styles from "./styles.scss";
import { Group } from '~/components/containers/Group'; import { Group } from "~/components/containers/Group";
import classNames from 'classnames'; import classNames from "classnames";
import { Filler } from '~/components/containers/Filler'; import { Filler } from "~/components/containers/Filler";
import { ERRORS } from '~/constants/errors'; import { ERRORS } from "~/constants/errors";
import { t } from '~/utils/trans'; import { t } from "~/utils/trans";
interface IProps { interface IProps {
is_loading?: boolean; is_loading?: boolean;
@ -17,8 +17,6 @@ const NodeNoComments: FC<IProps> = ({ is_loading = false }) => (
<div className={styles.card}>{!is_loading && t(ERRORS.NO_COMMENTS)}</div> <div className={styles.card}>{!is_loading && t(ERRORS.NO_COMMENTS)}</div>
<div className={styles.card} /> <div className={styles.card} />
</Group> </Group>
<Filler />
</> </>
); );

View file

@ -1,30 +1,34 @@
@keyframes fade { @keyframes fade {
0% { 0% {
opacity: 0.25; // opacity: 0.25;
} }
100% { 100% {
opacity: 0.1; // opacity: 0.1;
} }
} }
.wrap { .wrap {
user-select: none;
height: 300px; height: 300px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
@include after_shade($node_bg); // @include after_shade($node_bg);
&:global(.is_loading) { &:global(.is_loading) {
opacity: 1;
.card { .card {
background: $placeholder_bg;
animation: fade 0.5s infinite alternate; animation: fade 0.5s infinite alternate;
} }
} }
} }
.card { .card {
opacity: 0.2; opacity: 0.3;
border-radius: $radius; border-radius: $radius;
height: 96px; height: 96px;
background: $comment_bg; background: $placeholder_bg;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -33,7 +37,7 @@
color: transparentize(white, 0.5); color: transparentize(white, 0.5);
flex: 0 0 $comment_height; flex: 0 0 $comment_height;
@include outer_shadow(); // @include outer_shadow();
&:nth-child(2) { &:nth-child(2) {
// animation-delay: -300ms !important; // animation-delay: -300ms !important;

View file

@ -1,9 +1,16 @@
import React, { FC, useCallback, useEffect, useRef, useState, memo } from 'react'; import React, {
import * as styles from './styles.scss'; FC,
import { INode } from '~/redux/types'; useCallback,
import { createPortal } from 'react-dom'; useEffect,
import { NodePanelInner } from '~/components/node/NodePanelInner'; useRef,
import pick from 'ramda/es/pick'; useState,
memo
} from "react";
import * as styles from "./styles.scss";
import { INode } from "~/redux/types";
import { createPortal } from "react-dom";
import { NodePanelInner } from "~/components/node/NodePanelInner";
import pick from "ramda/es/pick";
interface IProps { interface IProps {
node: Partial<INode>; node: Partial<INode>;
@ -13,13 +20,25 @@ interface IProps {
can_like: boolean; can_like: boolean;
can_star: boolean; can_star: boolean;
is_loading?: boolean;
onEdit: () => void; onEdit: () => void;
onLike: () => void; onLike: () => void;
onStar: () => void; onStar: () => void;
} }
const NodePanel: FC<IProps> = memo( const NodePanel: FC<IProps> = memo(
({ node, layout, can_edit, can_like, can_star, onEdit, onLike, onStar }) => { ({
node,
layout,
can_edit,
can_like,
can_star,
is_loading,
onEdit,
onLike,
onStar
}) => {
const [stack, setStack] = useState(false); const [stack, setStack] = useState(false);
const ref = useRef(null); const ref = useRef(null);
@ -35,12 +54,12 @@ const NodePanel: FC<IProps> = memo(
useEffect(() => { useEffect(() => {
getPlace(); getPlace();
window.addEventListener('scroll', getPlace); window.addEventListener("scroll", getPlace);
window.addEventListener('resize', getPlace); window.addEventListener("resize", getPlace);
return () => { return () => {
window.removeEventListener('scroll', getPlace); window.removeEventListener("scroll", getPlace);
window.removeEventListener('resize', getPlace); window.removeEventListener("resize", getPlace);
}; };
}, [layout]); }, [layout]);
@ -57,6 +76,7 @@ const NodePanel: FC<IProps> = memo(
can_edit={can_edit} can_edit={can_edit}
can_like={can_like} can_like={can_like}
can_star={can_star} can_star={can_star}
is_loading={is_loading}
/>, />,
document.body document.body
) )
@ -69,6 +89,7 @@ const NodePanel: FC<IProps> = memo(
can_edit={can_edit} can_edit={can_edit}
can_like={can_like} can_like={can_like}
can_star={can_star} can_star={can_star}
is_loading={is_loading}
/> />
)} )}
</div> </div>

View file

@ -1,10 +1,11 @@
import React, { FC } from 'react'; import React, { FC } from "react";
import * as styles from './styles.scss'; import * as styles from "./styles.scss";
import { Group } from '~/components/containers/Group'; import { Group } from "~/components/containers/Group";
import { Filler } from '~/components/containers/Filler'; import { Filler } from "~/components/containers/Filler";
import { Icon } from '~/components/input/Icon'; import { Icon } from "~/components/input/Icon";
import { INode } from '~/redux/types'; import { INode } from "~/redux/types";
import classNames from 'classnames'; import classNames from "classnames";
import { Placeholder } from "~/components/placeholders/Placeholder";
interface IProps { interface IProps {
node: Partial<INode>; node: Partial<INode>;
@ -13,6 +14,9 @@ interface IProps {
can_edit: boolean; can_edit: boolean;
can_like: boolean; can_like: boolean;
can_star: boolean; can_star: boolean;
is_loading: boolean;
onEdit: () => void; onEdit: () => void;
onLike: () => void; onLike: () => void;
onStar: () => void; onStar: () => void;
@ -21,20 +25,34 @@ interface IProps {
const NodePanelInner: FC<IProps> = ({ const NodePanelInner: FC<IProps> = ({
node: { title, user, is_liked, is_heroic }, node: { title, user, is_liked, is_heroic },
stack, stack,
can_star, can_star,
can_edit, can_edit,
can_like, can_like,
is_loading,
onStar, onStar,
onEdit, onEdit,
onLike, onLike
}) => { }) => {
return ( return (
<div className={classNames(styles.wrap, { stack })}> <div className={classNames(styles.wrap, { stack })}>
<div className={styles.content}> <div className={styles.content}>
<Group horizontal className={styles.panel}> <Group horizontal className={styles.panel}>
<Filler> <Filler>
<div className={styles.title}>{title || '...'}</div> <div className={styles.title}>
{user && user.username && <div className={styles.name}>~{user.username}</div>} {is_loading ? <Placeholder width="40%" /> : title || "..."}
</div>
{user && user.username && (
<div className={styles.name}>
{is_loading ? (
<Placeholder width="100px" />
) : (
`~${user.username}`
)}
</div>
)}
</Filler> </Filler>
</Group> </Group>

View file

@ -0,0 +1,31 @@
import React, { FC, memo } from "react";
import styles from "./styles.scss";
import cell_style from "~/components/node/NodeRelatedItem/styles.scss";
import { Group } from "~/components/containers/Group";
import { Placeholder } from "~/components/placeholders/Placeholder";
import range from "ramda/es/range";
import classNames from "classnames";
interface IProps {}
const NodeRelatedPlaceholder: FC<IProps> = memo(() => {
return (
<Group className={classNames(styles.wrap, styles.placeholder)}>
<div className={styles.title}>
<div className={styles.line} />
<div className={styles.text}>
<Placeholder />
</div>
<div className={styles.line} />
</div>
<div className={styles.grid}>
{range(0, 6).map(el => (
<div className={cell_style.item} key={el} />
))}
</div>
</Group>
);
});
export { NodeRelatedPlaceholder };

View file

@ -36,3 +36,15 @@
.text { .text {
margin: 0 $gap; margin: 0 $gap;
} }
.placeholder {
.text {
opacity: 1;
}
.grid {
div {
background: $placeholder_bg;
}
}
}

View file

@ -0,0 +1,17 @@
import React, { FC, memo } from "react";
import { Tags } from "../Tags";
import { ITag } from "~/redux/types";
interface IProps {
is_editable?: boolean;
tags: ITag[];
onChange?: (tags: string[]) => void;
}
const NodeTagsPlaceholder: FC<IProps> = memo(
({ is_editable, tags, onChange }) => (
<Tags tags={tags} is_editable={is_editable} onTagsChange={onChange} />
)
);
export { NodeTagsPlaceholder };

View file

@ -6,13 +6,12 @@ import React, {
useEffect, useEffect,
KeyboardEvent, KeyboardEvent,
ChangeEvent, ChangeEvent,
useRef, useRef
} from 'react'; } 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";
import uniq from 'ramda/es/uniq'; import uniq from "ramda/es/uniq";
import assocPath from 'ramda/es/assocPath';
type IProps = HTMLAttributes<HTMLDivElement> & { type IProps = HTMLAttributes<HTMLDivElement> & {
tags: Partial<ITag>[]; tags: Partial<ITag>[];
@ -20,8 +19,13 @@ type IProps = HTMLAttributes<HTMLDivElement> & {
onTagsChange?: (tags: string[]) => void; onTagsChange?: (tags: string[]) => void;
}; };
export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props }) => { export const Tags: FC<IProps> = ({
const [input, setInput] = useState(''); tags,
is_editable,
onTagsChange,
...props
}) => {
const [input, setInput] = useState("");
const [data, setData] = useState([]); const [data, setData] = useState([]);
const timer = useRef(null); const timer = useRef(null);
@ -35,17 +39,17 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
const onKeyUp = useCallback( const onKeyUp = useCallback(
({ key }: KeyboardEvent) => { ({ key }: KeyboardEvent) => {
if (key === 'Backspace' && input === '' && data.length) { if (key === "Backspace" && input === "" && data.length) {
setData(data.slice(0, data.length - 1)); setData(data.slice(0, data.length - 1));
setInput(data[data.length - 1].title); setInput(data[data.length - 1].title);
} }
if (key === 'Enter' || key === ',' || key === 'Comma') { if (key === "Enter" || key === "," || key === "Comma") {
setData( setData(
uniq([ uniq([
...data, ...data,
...input ...input
.split(',') .split(",")
.map((title: string) => .map((title: string) =>
title title
.trim() .trim()
@ -55,11 +59,11 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
.filter(el => el.length > 0) .filter(el => el.length > 0)
.filter(el => !tags.some(tag => tag.title.trim() === el.trim())) .filter(el => !tags.some(tag => tag.title.trim() === el.trim()))
.map(title => ({ .map(title => ({
title, title
})), }))
]) ])
); );
setInput(''); setInput("");
} }
}, },
[input, setInput, data, setData] [input, setInput, data, setData]
@ -71,12 +75,16 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
if (!items.length) return; if (!items.length) return;
setData(items); setData(items);
setInput(''); setInput("");
onTagsChange(uniq([...tags, ...items]).map(tag => tag.title)); onTagsChange(uniq([...tags, ...items]).map(tag => tag.title));
}, [tags, data, onTagsChange, input, setInput]); }, [tags, data, onTagsChange, input, setInput]);
useEffect(() => { useEffect(() => {
setData(data.filter(({ title }) => !tags.some(tag => tag.title.trim() === title.trim()))); setData(
data.filter(
({ title }) => !tags.some(tag => tag.title.trim() === title.trim())
)
);
}, [tags]); }, [tags]);
return ( return (
@ -90,7 +98,12 @@ export const Tags: FC<IProps> = ({ tags, is_editable, onTagsChange, ...props })
))} ))}
{is_editable && ( {is_editable && (
<Tag tag={{ title: input }} onInput={onInput} onKeyUp={onKeyUp} onBlur={onSubmit} /> <Tag
tag={{ title: input }}
onInput={onInput}
onKeyUp={onKeyUp}
onBlur={onSubmit}
/>
)} )}
</TagField> </TagField>
); );

View file

@ -1,6 +1,6 @@
.placeholder { .placeholder {
height: 1em; height: 1em;
width: 120px; width: 120px;
background: transparentize(white, 0.95); background: $placeholder_bg;
border-radius: 1em; border-radius: 1em;
} }

View file

@ -1,27 +1,36 @@
import React, { FC, createElement, useEffect, useCallback, useState, useMemo, memo } from 'react'; import React, {
import { RouteComponentProps } from 'react-router'; FC,
import { connect } from 'react-redux'; createElement,
import { canEditNode, canLikeNode, canStarNode } from '~/utils/node'; useEffect,
import { selectNode } from '~/redux/node/selectors'; useCallback,
import { Card } from '~/components/containers/Card'; useState,
useMemo,
memo
} from "react";
import { RouteComponentProps } from "react-router";
import { connect } from "react-redux";
import { canEditNode, canLikeNode, canStarNode } from "~/utils/node";
import { selectNode } from "~/redux/node/selectors";
import { Card } from "~/components/containers/Card";
import { NodePanel } from '~/components/node/NodePanel'; import { NodePanel } from "~/components/node/NodePanel";
import { Group } from '~/components/containers/Group'; import { Group } from "~/components/containers/Group";
import { Padder } from '~/components/containers/Padder'; import { Padder } from "~/components/containers/Padder";
import { NodeNoComments } from '~/components/node/NodeNoComments'; import { NodeNoComments } from "~/components/node/NodeNoComments";
import { NodeRelated } from '~/components/node/NodeRelated'; import { NodeRelated } from "~/components/node/NodeRelated";
import * as styles from './styles.scss'; import * as styles from "./styles.scss";
import { NodeComments } from '~/components/node/NodeComments'; import { NodeComments } from "~/components/node/NodeComments";
import { NodeTags } from '~/components/node/NodeTags'; import { NodeTags } from "~/components/node/NodeTags";
import { NODE_COMPONENTS, NODE_INLINES } from '~/redux/node/constants'; import { NODE_COMPONENTS, NODE_INLINES } from "~/redux/node/constants";
import * as NODE_ACTIONS from '~/redux/node/actions'; import * as NODE_ACTIONS from "~/redux/node/actions";
import { CommentForm } from '~/components/node/CommentForm'; import { CommentForm } from "~/components/node/CommentForm";
import { selectUser } from '~/redux/auth/selectors'; import { selectUser } from "~/redux/auth/selectors";
import pick from 'ramda/es/pick'; import pick from "ramda/es/pick";
import { NodeRelatedPlaceholder } from "~/components/node/NodeRelated/placeholder";
const mapStateToProps = state => ({ const mapStateToProps = state => ({
node: selectNode(state), node: selectNode(state),
user: selectUser(state), user: selectUser(state)
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
@ -30,7 +39,7 @@ const mapDispatchToProps = {
nodeSetCoverImage: NODE_ACTIONS.nodeSetCoverImage, nodeSetCoverImage: NODE_ACTIONS.nodeSetCoverImage,
nodeEdit: NODE_ACTIONS.nodeEdit, nodeEdit: NODE_ACTIONS.nodeEdit,
nodeLike: NODE_ACTIONS.nodeLike, nodeLike: NODE_ACTIONS.nodeLike,
nodeStar: NODE_ACTIONS.nodeStar, nodeStar: NODE_ACTIONS.nodeStar
}; };
type IProps = ReturnType<typeof mapStateToProps> & type IProps = ReturnType<typeof mapStateToProps> &
@ -40,9 +49,15 @@ type IProps = ReturnType<typeof mapStateToProps> &
const NodeLayoutUnconnected: FC<IProps> = memo( const NodeLayoutUnconnected: FC<IProps> = memo(
({ ({
match: { match: {
params: { id }, params: { id }
},
node: {
is_loading,
is_loading_comments,
comments = [],
current: node,
related
}, },
node: { is_loading, is_loading_comments, comments = [], current: node, related },
user, user,
user: { is_user }, user: { is_user },
nodeGotoNode, nodeGotoNode,
@ -50,8 +65,10 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
nodeEdit, nodeEdit,
nodeLike, nodeLike,
nodeStar, nodeStar,
nodeSetCoverImage, nodeSetCoverImage
}) => { }) => {
// const is_loading = true;
const [layout, setLayout] = useState({}); const [layout, setLayout] = useState({});
const updateLayout = useCallback(() => setLayout({}), []); const updateLayout = useCallback(() => setLayout({}), []);
@ -86,11 +103,12 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
}, [nodeSetCoverImage, node.cover]); }, [nodeSetCoverImage, node.cover]);
return ( return (
<Card className={styles.node} seamless key={id}> <Card className={styles.node} seamless>
{block && createElement(block, { node, is_loading, updateLayout, layout })} {block &&
createElement(block, { node, is_loading, updateLayout, layout })}
<NodePanel <NodePanel
node={pick(['title', 'user', 'is_liked', 'is_heroic'], node)} node={pick(["title", "user", "is_liked", "is_heroic"], node)}
layout={layout} layout={layout}
can_edit={can_edit} can_edit={can_edit}
can_like={can_like} can_like={can_like}
@ -98,6 +116,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
onEdit={onEdit} onEdit={onEdit}
onLike={onLike} onLike={onLike}
onStar={onStar} onStar={onStar}
is_loading={is_loading}
/> />
<Group> <Group>
@ -106,32 +125,57 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
<Group className={styles.comments}> <Group className={styles.comments}>
{inline_block && ( {inline_block && (
<div className={styles.inline_block}> <div className={styles.inline_block}>
{createElement(inline_block, { node, is_loading, updateLayout, layout })} {createElement(inline_block, {
node,
is_loading,
updateLayout,
layout
})}
</div> </div>
)} )}
{is_loading_comments || !comments.length ? ( {is_loading ||
<NodeNoComments is_loading={is_loading_comments} /> is_loading_comments ||
(!comments.length && !inline_block) ? (
<NodeNoComments
is_loading={is_loading_comments || is_loading}
/>
) : ( ) : (
<NodeComments comments={comments} /> <NodeComments comments={comments} />
)} )}
{is_user && <CommentForm id={0} />} {is_user && !is_loading && <CommentForm id={0} />}
</Group> </Group>
<div className={styles.panel}> <div className={styles.panel}>
<Group style={{ flex: 1, minWidth: 0 }}> <Group style={{ flex: 1, minWidth: 0 }}>
<NodeTags is_editable={is_user} tags={node.tags} onChange={onTagsChange} /> {!is_loading && (
<NodeTags
is_editable={is_user}
tags={node.tags}
onChange={onTagsChange}
/>
)}
{related && {is_loading && <NodeRelatedPlaceholder />}
{!is_loading &&
related &&
related.albums && related.albums &&
Object.keys(related.albums).map(album => ( Object.keys(related.albums).map(album => (
<NodeRelated title={album} items={related.albums[album]} key={album} /> <NodeRelated
title={album}
items={related.albums[album]}
key={album}
/>
))} ))}
{related && related.similar && related.similar.length > 0 && ( {!is_loading &&
<NodeRelated title="ПОХОЖИЕ" items={related.similar} /> related &&
)} related.similar &&
related.similar.length > 0 && (
<NodeRelated title="ПОХОЖИЕ" items={related.similar} />
)}
</Group> </Group>
</div> </div>
</Group> </Group>

View file

@ -7,6 +7,10 @@
.comments { .comments {
flex: 3 1; flex: 3 1;
min-width: 0; min-width: 0;
display: flex;
align-items: stretch;
justify-content: flex-start;
flex-direction: column;
} }
.panel { .panel {

View file

@ -1,4 +1,4 @@
@import 'colors'; @import "colors";
$cell: 280px; $cell: 280px;
$gap: 10px; $gap: 10px;
@ -13,6 +13,7 @@ $cell_radius: $radius;
$panel_radius: $radius; $panel_radius: $radius;
$input_radius: $radius; $input_radius: $radius;
$dialog_radius: $radius * 2; $dialog_radius: $radius * 2;
$placeholder_bg: transparentize(white, 0.96);
$input_height: 36px; $input_height: 36px;
$info_height: 24px; $info_height: 24px;
@ -30,9 +31,9 @@ $extra_light: 200;
$upload_button_height: 52px; $upload_button_height: 52px;
$font: Montserrat, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, $font: Montserrat, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
'Noto Color Emoji'; "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
$font_48_semibold: $semibold 48px $font; $font_48_semibold: $semibold 48px $font;
$font_48_bold: $bold 48px $font; $font_48_bold: $bold 48px $font;
@ -60,11 +61,14 @@ $font_8_semibold: $semibold 8px $font;
$font_cell_title: $bold 30px $font; $font_cell_title: $bold 30px $font;
$font_hero_title: $bold 40px $font; $font_hero_title: $bold 40px $font;
$shadow_depth_1: transparentize(black, 0.8) 0 1px, inset transparentize(white, 0.98) 0 1px; $shadow_depth_1: transparentize(black, 0.8) 0 1px,
$shadow_depth_2: transparentize(black, 0.8) 0 2px, inset transparentize(white, 0.98) 0 1px; inset transparentize(white, 0.98) 0 1px;
$shadow_depth_2: transparentize(black, 0.8) 0 2px,
inset transparentize(white, 0.98) 0 1px;
$comment_shadow: $shadow_depth_2; $comment_shadow: $shadow_depth_2;
$node_shadow: transparentize(black, 0.8) 0 2px, transparentize(black, 0.8) 0 2px 4px; $node_shadow: transparentize(black, 0.8) 0 2px,
transparentize(black, 0.8) 0 2px 4px;
$tag_height: 26px; $tag_height: 26px;
@ -73,15 +77,18 @@ $input_shadow_error: inset $red 0 0 0 1px;
$input_shadow_filled: $input_shadow; $input_shadow_filled: $input_shadow;
@mixin outer_shadow() { @mixin outer_shadow() {
box-shadow: inset transparentize(white, 0.95) 0 1px, transparentize(black, 0.8) -1px -1px; box-shadow: inset transparentize(white, 0.95) 0 1px,
transparentize(black, 0.8) -1px -1px;
} }
@mixin inner_shadow() { @mixin inner_shadow() {
box-shadow: inset transparentize(white, 0.95) 0 -1px, inset transparentize(black, 0.5) 0 1px; box-shadow: inset transparentize(white, 0.95) 0 -1px,
inset transparentize(black, 0.5) 0 1px;
} }
@mixin input_shadow() { @mixin input_shadow() {
box-shadow: inset transparentize(white, 0.92) 0 -1px, inset transparentize(black, 0.8) 0 1px; box-shadow: inset transparentize(white, 0.92) 0 -1px,
inset transparentize(black, 0.8) 0 1px;
} }
@mixin modal_mixin() { @mixin modal_mixin() {
@ -97,7 +104,7 @@ $input_shadow_filled: $input_shadow;
position: $position; position: $position;
&::after { &::after {
content: ' '; content: " ";
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 0; left: 0;