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

added horizon theme

This commit is contained in:
Fedor Katurov 2022-08-14 14:00:18 +07:00
parent ce7737b3cd
commit f26f74c35f
23 changed files with 523 additions and 144 deletions

View file

@ -14,7 +14,7 @@
}
.button {
background: $danger_gradient;
background: $flow_gradient;
width: $bar_height;
height: $bar_height;
border-radius: $bar_height * 0.5;

View file

@ -29,15 +29,18 @@ const BasicCurveChart: VFC<BasicCurveChartProps> = ({
(acc, val, index) => [
...acc,
index === 0
? { x: borderGap, y: height - (val / max) * (height - gap * 2) - gap }
? {
x: borderGap,
y: height - (val / max) * (height - gap * 2) - gap,
}
: {
x: ((width - borderGap) / (items.length - 1)) * index,
y: height - (val / max) * (height - gap * 2) - gap,
},
],
[]
[],
),
[height, width, items, gap]
[height, width, items, gap],
);
if (!points.length) {
@ -49,20 +52,29 @@ const BasicCurveChart: VFC<BasicCurveChartProps> = ({
{...props}
width="100%"
height="100%"
viewBox={`0 0 ${width} ${height}`}
viewBox={`0 0 ${width} ${height * 1.05}`}
preserveAspectRatio="none"
>
<defs>
<filter id="f1" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
</filter>
<filter id="brighter">
<feComponentTransfer>
<feFuncR type="linear" slope="3" />
<feFuncG type="linear" slope="3" />
<feFuncB type="linear" slope="3" />
</feComponentTransfer>
</filter>
</defs>
<path
d={makeBezierCurve(points)}
fill="none"
x={0}
y={0}
y={gap / 2}
opacity={0.5}
stroke={stroke}
strokeWidth={2}
strokeLinecap="round"
@ -74,6 +86,7 @@ const BasicCurveChart: VFC<BasicCurveChartProps> = ({
fill="none"
x={0}
y={0}
opacity={0.3}
stroke={stroke}
strokeWidth={2}
strokeLinecap="round"
@ -84,9 +97,11 @@ const BasicCurveChart: VFC<BasicCurveChartProps> = ({
fill="none"
x={0}
y={0}
stroke={lighten(stroke, 0.1)}
stroke={stroke}
opacity={1}
strokeWidth={1}
strokeLinecap="round"
filter="url(#brighter)"
/>
</svg>
);

View file

@ -15,11 +15,19 @@ interface StatsGraphCardProps extends CardProps {
right?: string | number;
}
const StatsGraphCard: VFC<StatsGraphCardProps> = ({ total, title, data, left, right }) => (
const StatsGraphCard: VFC<StatsGraphCardProps> = ({
total,
title,
data,
left,
right,
}) => (
<StatsCard
title={title}
total={total}
background={<BasicCurveChart items={data} />}
background={
<BasicCurveChart items={data} stroke={'var(--color_primary)'} />
}
className={styles.card}
>
<div className={styles.content}>

View file

@ -32,7 +32,7 @@ const EditorButtons: FC = () => {
<Button
title={isTablet ? undefined : 'Сохранить'}
iconRight="check"
color={values.is_promoted ? 'danger' : 'info'}
color={values.is_promoted ? 'flow' : 'lab'}
disabled={isSubmitting}
type="submit"
/>

View file

@ -19,7 +19,7 @@ const EditorPublicSwitch: FC<IProps> = () => {
return (
<Button
color={values.is_promoted ? 'danger' : 'info'}
color={values.is_promoted ? 'flow' : 'lab'}
type="button"
size="giant"
label={

View file

@ -39,7 +39,7 @@ const EditorUploadButton: FC<IProps> = ({
[type, uploadFiles],
);
const color = values.is_promoted ? 'danger' : 'info';
const color = values.is_promoted ? 'flow' : 'lab';
return (
<Button

View file

@ -27,6 +27,7 @@ type IButtonProps = DetailedHTMLProps<
| 'outline'
| 'link'
| 'gray'
| 'flow'
| 'lab'
| 'outline-white'
| 'flat';

View file

@ -244,7 +244,11 @@
}
.lab {
background: $color_lab;
background: $lab_gradient;
}
.flow {
background: $flow_gradient;
}
.flat {

View file

@ -96,16 +96,16 @@
opacity: 1;
svg {
fill: $color_danger;
fill: $color_like;
}
.like_count {
color: $color_danger;
color: $color_like;
}
}
&:hover {
fill: $color_danger;
fill: $color_like;
animation: pulse 0.75s infinite;
.like_count {

View file

@ -3,12 +3,6 @@ import React, { FC, FocusEventHandler, useCallback } from 'react';
import { TagWrapper } from '~/components/tags/TagWrapper';
import { ITag } from '~/types';
const getTagFeature = (tag: Partial<ITag>) => {
if (tag?.title?.substr(0, 1) === '/') return 'green';
return '';
};
interface IProps {
tag: Partial<ITag>;
size?: 'normal' | 'big';
@ -44,9 +38,11 @@ const Tag: FC<IProps> = ({
onDelete(tag.ID!);
}, [onDelete, tag]);
const isAlbumTag = tag?.title?.substr(0, 1) === '/';
return (
<TagWrapper
feature={getTagFeature(tag)}
color={isAlbumTag ? 'primary' : undefined}
size={size}
deletable={deletable}
hoverable={hoverable}

View file

@ -9,16 +9,23 @@ import styles from './styles.module.scss';
interface IProps {
selected: boolean;
title: string;
type: string;
type: 'enter' | 'right' | 'tag';
onSelect: (val: string) => void;
}
const TagAutocompleteRow: FC<IProps> = ({ selected, type, title, onSelect }) => {
const TagAutocompleteRow: FC<IProps> = ({
selected,
type,
title,
onSelect,
}) => {
const onClick = useCallback(() => onSelect(title), [title, onSelect]);
return (
<div
className={classNames(styles.row, styles[type], { [styles.selected]: selected })}
className={classNames(styles.row, styles[type], {
[styles.selected]: selected,
})}
onClick={onClick}
>
<Icon icon={type} size={16} />

View file

@ -23,7 +23,7 @@ $row_height: 26px;
}
&.right {
color: lighten($color_primary, 4%);
color: $color_primary;
opacity: 1;
}

View file

@ -7,8 +7,8 @@ import { Icon } from '~/components/input/Icon';
import styles from './styles.module.scss';
interface IProps {
feature?: string;
size?: string;
color?: 'primary' | 'danger' | 'info' | 'black' | 'default';
deletable?: boolean;
hoverable?: boolean;
editing?: boolean;
@ -19,8 +19,8 @@ interface IProps {
}
const TagWrapper: FC<IProps> = ({
color = 'default',
children,
feature,
size,
deletable,
hoverable,
@ -32,7 +32,7 @@ const TagWrapper: FC<IProps> = ({
}) => {
const canBeDeleted = deletable && !editing && !hasInput;
const onDeletePress = useCallback(
event => {
(event) => {
if (!onDelete) {
return;
}
@ -40,18 +40,23 @@ const TagWrapper: FC<IProps> = ({
event.stopPropagation();
onDelete();
},
[onDelete]
[onDelete],
);
return (
<div
className={classNames(styles.tag, feature, size, {
is_hoverable: hoverable,
is_editing: editing,
deletable: canBeDeleted,
input: hasInput,
clickable: onClick,
})}
className={classNames(
styles.tag,
size && styles[`size-${size}`],
styles[`color-${color}`],
{
[styles.hoverable]: hoverable,
[styles.editing]: editing,
[styles.deletable]: canBeDeleted,
[styles.input]: hasInput,
[styles.clickable]: onClick,
},
)}
onClick={onClick}
>
<div className={styles.hole} />

View file

@ -25,39 +25,37 @@ $big: 1.2;
z-index: 40;
}
&:global(.big) {
height: $tag_height * $big;
font: $font_16_semibold;
border-radius: ($tag_height * $big * 0.5) 3px 3px ($tag_height * $big * 0.5);
.hole {
width: $tag_height * $big;
height: $tag_height * $big;
}
}
&:global(.is_hoverable) {
&.hoverable {
cursor: pointer;
}
&:global(.is_editing) {
&.editing {
cursor: pointer;
background-color: lighten($content_bg_light, 10%);
background-color: $content_bg;
}
&:global(.red) {
&.input {
color: transparent !important;
min-width: 100px;
}
&.clickable {
cursor: pointer;
}
&.color-danger {
background: $danger_gradient;
}
&:global(.blue) {
&.color-info {
background: $info_gradient;
}
&:global(.green) {
&.color-primary {
background: $primary_gradient;
}
&:global(.black) {
&.color-black {
background: transparentize(black, 0.7);
box-shadow: none;
color: $gray_75;
@ -68,13 +66,15 @@ $big: 1.2;
}
}
&:global(.input) {
color: transparent !important;
min-width: 100px;
}
&.size-big {
height: $tag_height * $big;
font: $font_16_semibold;
border-radius: ($tag_height * $big * 0.5) 3px 3px ($tag_height * $big * 0.5);
&:global(.clickable) {
cursor: pointer;
.hole {
width: $tag_height * $big;
height: $tag_height * $big;
}
}
input {
@ -124,7 +124,8 @@ $big: 1.2;
}
button.delete {
box-shadow: inset $gray_90 1px 0, transparentize(black, 0.7) -1px 0;
box-shadow: inset transparentize(white, 0.95) 1px 0,
transparentize(black, 0.7) -1px 0;
width: 24px;
height: $tag_height;
z-index: 24;

View file

@ -86,7 +86,7 @@
white-space: nowrap;
&:hover {
color: $color_danger;
color: $color_link;
}
&::before {
@ -109,7 +109,7 @@
width: 6px;
height: 6px;
border-radius: 4px;
background: lighten($color_danger, 10%);
background: $color_link;
right: 12px;
top: 6px;
transition: opacity 0.5s;
@ -123,11 +123,11 @@
}
&.lab::after {
background: lighten($color_lab, 10%);
background: $color_lab;
}
&.boris::after {
background: lighten($color_primary, 10%);
background: $color_primary;
}
@include tablet {

View file

@ -19,13 +19,8 @@ const placeholder = 'Добавить';
const prepareInput = (input: string): string[] => {
return input
.split(',')
.map((title: string) =>
title
.trim()
.substring(0, 64)
.toLowerCase(),
)
.filter(el => el.length > 0);
.map((title: string) => title.trim().substring(0, 64).toLowerCase())
.filter((el) => el.length > 0);
};
interface IProps {
@ -88,7 +83,7 @@ const TagInput: FC<IProps> = ({ exclude, onAppend, onClearTag, onSubmit }) => {
const onFocus = useCallback(() => setFocused(true), []);
const onBlur = useCallback(
event => {
(event) => {
if (!wrapper.current || !ref.current) {
return;
}
@ -122,9 +117,7 @@ const TagInput: FC<IProps> = ({ exclude, onAppend, onClearTag, onSubmit }) => {
[onAppend, setInput],
);
const feature = useMemo(() => (input?.substr(0, 1) === '/' ? 'green' : ''), [
input,
]);
const isAlbumTag = useMemo(() => input?.substr(0, 1) === '/', [input]);
useEffect(() => {
if (!focused) return;
@ -138,7 +131,7 @@ const TagInput: FC<IProps> = ({ exclude, onAppend, onClearTag, onSubmit }) => {
<TagWrapper
title={input || placeholder}
hasInput={true}
feature={feature}
color={isAlbumTag ? 'primary' : undefined}
>
<input
type="text"

View file

@ -19,8 +19,7 @@
width: 100%;
height: 100vh;
overflow: hidden;
background: 50% 0 no-repeat url('../../sprites/boris_bg.svg');
background-size: cover;
background: $boris_background;
}
.header {

View file

@ -1,58 +1,45 @@
// palette (use inside)
$yellow: #ffd60f;
$dark_blue: #592071;
$blue: #582cd0;
$green: #00d2b9;
$wisegreen: #007962;
$olive: #6cb337;
$red: #ff3344;
$orange: #ff7549;
$lightgreen: lighten(adjust_hue(#007962, -30deg), 10%);
$soft_blue: #3c75ff;
$brown: #23201f;
// main definitions (move to --vars)
$color_primary: $wisegreen;
$color_danger: $red;
$color_online: $olive;
$color_offline: $red;
$color_link: $red;
$color_flow: $red;
$color_lab: $blue;
$color_primary: var(--color_primary);
$color_danger: var(--color_danger);
$color_online: var(--color_online);
$color_offline: var(--color_offline);
$color_link: var(--color_link);
$color_flow: var(--color_flow);
$color_lab: var(--color_lab);
$color_boris: var(--color_boris);
$color_like: var(--color_like);
// gradients (move to --vars)
$danger_gradient: linear-gradient(165deg, $orange -50%, $color_danger 150%);
$info_gradient: linear-gradient(170deg, $blue, $dark_blue);
$warning_gradient: linear-gradient(165deg, $yellow -50%, $color_danger 150%);
$primary_gradient: linear-gradient(
170deg,
$lightgreen -50%,
$color_primary 150%
);
$magic_gradient: linear-gradient(260deg, $soft_blue -50%, #7b2653 150%);
$global_loader_gradient: linear-gradient(
90deg,
$dark_blue,
$soft_blue,
$dark_blue
);
$danger_gradient: var(--danger_gradient);
$info_gradient: var(--info_gradient);
$warning_gradient: var(--warning_gradient);
$primary_gradient: var(--primary_gradient);
$magic_gradient: var(--magic_gradient);
$global_loader_gradient: var(--global_loader_gradient);
$flow_gradient: var(--flow_gradient);
$lab_gradient: var(--lab_gradient);
// backgrounds (move to --vars)
$content_bg: $brown;
$content_bg_dark: darken($brown, 2%);
$content_bg_darker: darken($brown, 4%);
$content_bg_light: lighten($brown, 2%);
$content_bg_lighter: lighten($brown, 4%);
$content_bg_lightest: lighten($brown, 6%);
$content_bg: var(--content_bg);
$content_bg_dark: var(--content_bg_dark);
$content_bg_darker: var(--content_bg_darker);
$content_bg_light: var(--content_bg_light);
$content_bg_lighter: var(--content_bg_lighter);
$content_bg_lightest: var(--content_bg_lightest);
$content_bg_success: transparentize($wisegreen, 0.7);
$content_bg_info: transparentize($blue, 0.5);
$content_bg_danger: transparentize($red, 0.5);
$content_bg_backdrop: transparentize($content_bg, 0.2);
$content_bg_success: var(--content_bg_success);
$content_bg_info: var(--content_bg_info);
$content_bg_danger: var(--content_bg_danger);
$content_bg_backdrop: var(--content_bg_backdrop);
// white shades (move to --vars)
$white: white;
$gray_25: mix($content_bg, white, 25%);
$gray_50: mix($content_bg, white, 50%);
$gray_75: mix($content_bg, white, 75%);
$gray_90: mix($content_bg, white, 92%);
$white: var(--white);
$gray_25: var(--gray_25);
$gray_50: var(--gray_50);
$gray_75: var(--gray_75);
$gray_90: var(--gray_90);
// global
$page_background: var(--page-background);
$page_background_top: var(--page-background-top);
$boris_background: var(--boris-background);

View file

@ -1,3 +1,6 @@
@use './themes/default' as theme_default;
@use './themes/horizon' as theme_horizon;
@import 'src/styles/variables';
@import 'photoswipe/dist/photoswipe';
@import 'photoswipe/dist/default-skin/default-skin';
@ -10,6 +13,9 @@
@import 'swiper/css/zoom';
@import 'swiper/css/navigation';
@include theme_default.apply();
@include theme_horizon.apply();
html {
min-height: 100vh;
box-sizing: border-box;
@ -17,7 +23,7 @@ html {
body {
min-height: 100vh;
background: url('../../src/sprites/noise.png') $content_bg;
background: $page_background;
color: $white;
font: $font_16_regular;
-webkit-font-smoothing: antialiased;
@ -32,8 +38,7 @@ body {
top: 0;
left: 0;
z-index: -1;
background: url('../../src/sprites/noise_top.png') 0% 0%;
background-size: 600px 600px;
background: $page_background_top;
pointer-events: none;
}
@ -68,7 +73,7 @@ body {
}
.done {
background-color: $green;
background-color: $color_primary;
}
h2 {
@ -76,7 +81,7 @@ h2 {
}
.username {
color: $color_primary;
color: $color_link;
font-weight: 600;
}

View file

@ -266,29 +266,25 @@
[data-popper-placement*='bottom'] & {
border-width: 0 10px 10px 10px;
border-color: transparent transparent lighten($content_bg_light, 6%)
transparent;
border-color: transparent transparent $content_bg_lightest transparent;
top: -10px;
}
[data-popper-placement*='top'] & {
border-width: 10px 10px 0 10px;
border-color: lighten($content_bg_light, 6%) transparent transparent
transparent;
border-color: $content_bg_lightest transparent transparent transparent;
bottom: -10px;
}
[data-popper-placement*='right'] & {
border-width: 10px 10px 10px 0;
border-color: transparent lighten($content_bg_light, 6%) transparent
transparent;
border-color: transparent $content_bg_lightest transparent transparent;
left: -10px;
}
[data-popper-placement*='left'] & {
border-width: 10px 0 10px 10px;
border-color: transparent transparent transparent
lighten($content_bg_light, 6%);
border-color: transparent transparent transparent $content_bg_lightest;
right: -10px;
}
}

View file

@ -0,0 +1,82 @@
// palette (use inside)
$_yellow: #ffd60f;
$_dark_blue: #592071;
$_blue: #582cd0;
$_green: #00d2b9;
$_wisegreen: #007962;
$_olive: #6cb337;
$_red: #ff3344;
$_orange: #ff7549;
$_lightgreen: lighten(adjust_hue(#007962, -30deg), 10%);
$_soft_blue: #3c75ff;
$_brown: #23201f;
@mixin apply {
:root {
// main definitions (move to --vars)
--color_primary: #{$_wisegreen};
--color_danger: #{$_red};
--color_online: #{$_olive};
--color_offline: #{$_red};
--color_link: #{$_red};
--color_like: #{$_red};
--color_flow: #{$_red};
--color_lab: #{$_blue};
--color_boris: #{$_wisegreen};
// gradients (move to --vars)
--danger_gradient: linear-gradient(165deg, #{$_orange} -50%, #{$_red} 150%);
--info_gradient: linear-gradient(170deg, #{$_blue}, #{$_dark_blue});
--warning_gradient: linear-gradient(
165deg,
#{$_yellow} -50%,
#{$_red} 150%
);
--primary_gradient: linear-gradient(
170deg,
#{$_lightgreen} -50%,
#{$_wisegreen} 150%
);
--magic_gradient: linear-gradient(
260deg,
#{$_soft_blue} -50%,
#7b2653 150%
);
--global_loader_gradient: linear-gradient(
90deg,
#{$_dark_blue},
#{$_soft_blue},
#{$_dark_blue}
);
--flow_gradient: var(--danger_gradient);
--lab_gradient: var(--info_gradient);
// backgrounds (move to --vars)
--content_bg: #{$_brown};
--content_bg_dark: #{darken($_brown, 2%)};
--content_bg_darker: #{darken($_brown, 4%)};
--content_bg_light: #{lighten($_brown, 2%)};
--content_bg_lighter: #{lighten($_brown, 4%)};
--content_bg_lightest: #{lighten($_brown, 6%)};
--content_bg_success: #{transparentize($_wisegreen, 0.7)};
--content_bg_info: #{transparentize($_blue, 0.5)};
--content_bg_danger: #{transparentize($_red, 0.5)};
--content_bg_backdrop: #{transparentize($_brown, 0.2)};
// white shades (move to --vars)
--white: white;
--gray_25: #{transparentize(white, 0.25)};
--gray_50: #{transparentize(white, 0.5)};
--gray_75: #{transparentize(white, 0.75)};
--gray_90: #{transparentize(white, 0.95)};
// page background
--page-background: url('../../../src/sprites/noise.png') 0% 0% #{$_brown};
--page-background-top: 600px 600px url('../../../src/sprites/noise_top.png')
0% 0%;
--boris-background: 50% 0 / cover no-repeat
url('../../sprites/boris_bg.svg');
}
}

View file

@ -0,0 +1,92 @@
// palette (use inside)
$_yellow: #ffd60f;
$_dark_blue: #592071;
$_blue: #582cd0;
$_green: #00d2b9;
$_wisegreen: #007962;
$_olive: #6cb337;
$_red: #ff3344;
$_orange: #ff7549;
$_lightgreen: lighten(adjust_hue(#007962, -30deg), 10%);
$_soft_blue: #7693d6;
$_cold: #1c1e26;
$_accent: #e95678;
$_mandarine: #f09483;
$_lemon: #fab795;
$_ocean: #25b0bc;
@mixin apply {
:root.theme_horizon {
// main definitions (move to --vars)
--color_primary: #{$_accent};
--color_danger: #{$_red};
--color_online: #{$_ocean};
--color_offline: #{$_mandarine};
--color_link: #{$_ocean};
--color_like: #{$_lemon};
--color_flow: #{$_red};
--color_lab: #{$_blue};
--color_boris: #{$_wisegreen};
// gradients (move to --vars)
--danger_gradient: linear-gradient(165deg, #{$_orange} -50%, #{$_red} 150%);
--info_gradient: linear-gradient(170deg, #{$_ocean}, #{$_soft_blue});
--warning_gradient: linear-gradient(
165deg,
#{$_yellow} -50%,
#{$_red} 150%
);
--primary_gradient: linear-gradient(
170deg,
#{$_mandarine} -150%,
#{$_accent} 100%
);
--magic_gradient: linear-gradient(
260deg,
#{$_accent} -50%,
#{$_orange} 150%
);
--global_loader_gradient: linear-gradient(
90deg,
#{$_lemon},
#{$_accent},
#{$_mandarine}
);
--flow_gradient: var(--primary_gradient);
--lab_gradient: var(--info_gradient);
// backgrounds (move to --vars)
--content_bg: #{$_cold};
--content_bg_dark: #{darken($_cold, 2%)};
--content_bg_darker: #{darken($_cold, 4%)};
--content_bg_light: #{lighten($_cold, 2%)};
--content_bg_lighter: #{lighten($_cold, 4%)};
--content_bg_lightest: #{lighten($_cold, 6%)};
--content_bg_success: #{transparentize($_accent, 0.7)};
--content_bg_info: #{transparentize($_lemon, 0.7)};
--content_bg_danger: #{transparentize($_red, 0.5)};
--content_bg_backdrop: #{transparentize($_cold, 0.2)};
// white shades (move to --vars)
--white: white;
--gray_25: #{transparentize(white, 0.25)};
--gray_50: #{transparentize(white, 0.5)};
--gray_75: #{transparentize(white, 0.75)};
--gray_90: #{transparentize(white, 0.95)};
// page background
--page-background: 50% 50% / cover no-repeat url('/images/horizon_bg.svg') #{darken(
$_cold,
4%
)} fixed;
--page-background-top: none;
--boris-background: linear-gradient(#{$_ocean} -200%, transparent 50%);
}
}