From 06b6fef43b069083e3dee18b91b63e7ef2c069cb Mon Sep 17 00:00:00 2001 From: Ilya Bychek Date: Thu, 27 Jun 2024 20:30:10 +0300 Subject: [PATCH] feat(website): add animations --- .../components/colors/Color.tsx | 298 +++++++++++------- .../components/colors/GradientScroll.tsx | 65 ++-- .../components/colors/Header.tsx | 29 +- .../components/colors/Pallete.tsx | 176 +++++------ .../components/colors/PalleteItem.tsx | 112 ++++--- .../components/colors/TextReadble.tsx | 120 +++---- website/plasma-website/package-lock.json | 121 ++++--- website/plasma-website/utils/hexToHSL.ts | 41 ++- website/plasma-website/utils/hexToRGB.ts | 87 +++-- 9 files changed, 598 insertions(+), 451 deletions(-) diff --git a/website/plasma-website/components/colors/Color.tsx b/website/plasma-website/components/colors/Color.tsx index 772f7a34ff..9b52d7c935 100644 --- a/website/plasma-website/components/colors/Color.tsx +++ b/website/plasma-website/components/colors/Color.tsx @@ -1,45 +1,123 @@ -import React, { ReactNode, useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import styled from 'styled-components'; -import { TextReadble } from './TextReadble'; import { useToast } from '@salutejs/plasma-b2c'; import type { ShowToastArgs } from '@salutejs/plasma-b2c'; import { IconCopyOutline } from '@salutejs/plasma-icons'; -import { convertHexToRgb } from '../../utils'; -import type { colorItem } from './PalleteItem'; -import { useRouter } from 'next/router'; -const ColorItemBackground = styled.div<{background: string}>` +import { convertHexToRgb } from '../../utils'; + +import { TextReadble } from './TextReadble'; +import type { colorItemType } from './PalleteItem'; + +const toastData: ShowToastArgs = { + text: '', + position: 'bottom', + role: 'status', + size: 'm', + view: 'dark', + timeout: 1000, +}; + +const ColorWrapper = styled.div<{ background: string }>` position: fixed; inset: 0; - background: ${({background}) => background}; + background: ${({ background }) => background}; z-index: 99; + transition: 400ms; `; -const ColorItem = styled.div<{color: string, number: undefined | string}>` +const ColorPalette = styled.div` + position: relative; + width: 100%; + height: calc(100vh - 15rem); + box-sizing: border-box; + padding: 0.125rem; + display: flex; + gap: 0.125rem; +`; + +const ColorItem = styled.div<{ color: string; colorText: boolean }>` font-size: 0.75rem; width: calc(100% / 15); height: 100%; border-radius: 0.5rem; display: flex; align-items: flex-end; - padding-left: 1rem; - background: linear-gradient( - ${({color}) => {return color}} 5rem, - transparent 80% + padding-left: 0.375rem; + padding-bottom: 0.375rem; + /* stylelint-disable */ + background: linear-gradient( + 180deg, + ${({ color }) => { + return color; + }} + 12%, + ${({ color }) => { + return color; + }}85 + 40%, + ${({ color }) => { + return color; + }}76 + 45%, + ${({ color }) => { + return color; + }}66 + 50%, + ${({ color }) => { + return color; + }}55 + 54.5%, + ${({ color }) => { + return color; + }}44 + 59.75%, + ${({ color }) => { + return color; + }}33 + 65%, + ${({ color }) => { + return color; + }}23 + 69.5%, + ${({ color }) => { + return color; + }}14 + 75%, + ${({ color }) => { + return color; + }}08 + 80%, + ${({ color }) => { + return color; + }}03 + 85%, + ${({ color }) => { + return color; + }}01 + 89.6%, + transparent 95% ); + /* stylelint-enable */ cursor: pointer; position: relative; - transition: 0.2s; - color: ${({number}) => Number(number) > 400 ? 'rgba(255, 255, 255,0.28)' : 'rgba(0, 0, 0,0.28)'}; - font-weight: 700; + transition: 400ms; + color: ${({ colorText }) => (colorText ? 'rgba(255, 255, 255,0.28)' : 'rgba(0, 0, 0,0.28)')}; + font-weight: var(--plasma-typo-body1-font-weight); + + &:hover { + font-weight: var(--plasma-typo-headline1-font-weight); + color: ${({ colorText }) => (colorText ? 'rgba(255, 255, 255,0.56)' : 'rgba(0, 0, 0, 0.56)')}; + } - &.selected{ + &.selected { + font-weight: var(--plasma-typo-headline1-font-weight); width: calc(100% / 7.5); - color: ${({number}) => Number(number) > 400 ? 'rgba(255, 255, 255,1)' : 'rgba(0, 0, 0, 1)'}; + color: ${({ colorText }) => (colorText ? 'rgba(255, 255, 255,1)' : 'rgba(0, 0, 0, 1)')}; } `; -const ColorItemText = styled.div<{number: number | string}>` +const ColorItemText = styled.div<{ direction: string }>` position: absolute; bottom: 10%; height: 11rem; @@ -47,77 +125,57 @@ const ColorItemText = styled.div<{number: number | string}>` display: flex; flex-direction: column; font-size: 4rem; - ${({number}) => Number(number) > 400 ? 'left' : 'right'}: 0.5rem; + ${({ direction }) => direction}: 0.5rem; z-index: 9998; + transition: 200ms; `; -const Colors = styled.div` - position: relative; - width: 100%; - height: calc(100vh - 15rem); - box-sizing: border-box; - padding: 0.125rem; - display: flex; - gap: 0.125rem; -`; - -const TextReadbleWrapper = styled.div` - width: 100%; - height: 15rem; - display: grid; - grid-template-columns: 50% 50%; - grid-template-rows: 7.5rem 7.5rem; -`; - -const toastData: ShowToastArgs = { - text: '', - position: 'bottom', - role: 'status', - size: 'm', - view: 'dark', - timeout: 1000, -}; - -const OpacityText = styled.div` - opacity: 0.6; -`; - -const Text = styled.div` - display: flex; -`; - -const IconCopy = styled(IconCopyOutline)` - scale: 1.7; - opacity: 0; - visibility: hidden; - transition: opacity 0.2s, visibility 0s linear 0.2s; -`; - -const ColorIndex = styled.div<{number: number | string}>` +const ColorIndex = styled.div<{ colorText: boolean; direction: string }>` font-size: 4rem; height: 4rem; z-index: 9999; - font-weight: 400; + font-weight: var(--plasma-typo-body1-font-weight); display: flex; align-items: center; gap: 2rem; - flex-direction: ${({number}) => Number(number) > 400 ? 'row' : 'row-reverse'}; - color: ${({number}) => Number(number) > 400 ? 'white' : 'black'}; + flex-direction: ${({ direction }) => (direction === 'left' ? 'row' : 'row-reverse')}; + color: ${({ colorText }) => (colorText ? 'rgba(255, 255, 255,1)' : 'rgba(0, 0, 0, 1)')}; - &:hover .copyIcon{ + &:hover .copyIcon { opacity: 0.6; visibility: visible; transition-delay: 0s; } `; +const ColorItemWrapperText = styled.div` + display: flex; + font-family: var(--plasma-typo-headline1-font-family); +`; +const ColorItemWrapperOpacityText = styled.div` + opacity: 0.6; +`; +const ColorItemWrapperIconCopy = styled(IconCopyOutline)` + scale: 1.7; + opacity: 0; + visibility: hidden; + transition: opacity 0.2s, visibility 0s linear 0.2s; +`; -export const Color: React.FC<{ color: string, colorItem: colorItem}> = ({ color , colorItem }) => { - const [selectedColor, setSelectedColor] = useState(color); - - const router = useRouter(); +const TextReadbleWrapper = styled.div` + width: 100%; + height: 15rem; + display: grid; + grid-template-columns: 50% 50%; + grid-template-rows: 7.5rem 7.5rem; +`; +export const Color: React.FC<{ + color: string; + colorItem: colorItemType; + handlerSetColor: (color?: string, colorItem?: colorItemType, code?: string) => void; +}> = ({ color, colorItem, handlerSetColor }) => { const { showToast } = useToast(); const copyToClipboard = async (text: string) => { @@ -136,59 +194,73 @@ export const Color: React.FC<{ color: string, colorItem: colorItem}> = ({ color } }; - const handlerSetColor = (color: string, code: string) => { - router.push({pathname: '/colors', query: { - color: colorItem?.name, - code: code - }}); - - setSelectedColor(color); - } + const widthText = 530; const colorsKeys = Object.keys(colorItem.colors).reverse() ?? []; - const rgb = convertHexToRgb(selectedColor); - const colorKeySelected = colorsKeys.find((colorKey) => colorItem.colors[colorKey] === selectedColor); + const rgb = convertHexToRgb(color); + // const colorKeySelected = colorsKeys.find((colorKey) => colorItem.colors[colorKey] === color); + const colorIndex = colorsKeys.findIndex((colorKey) => colorItem.colors[colorKey] === color); + const colorText = + colorItem.textColor[ + colorItem.textColor.length - 1 - colorsKeys.findIndex((colorKey) => colorItem.colors[colorKey] === color) + ]; + + const [direction, setDirection] = useState(null); useEffect(() => { - setSelectedColor(color); - }, [color]) - + const windowWidth = window.innerWidth; + const item = windowWidth / 15; + const d = item * colorIndex < windowWidth - widthText ? 'left' : 'right'; + setDirection(d); + }, [color]); return ( - - + + {colorsKeys.map((colorKey) => ( - handlerSetColor(colorItem.colors[colorKey], colorKey)} color={colorItem.colors[colorKey]} className={selectedColor === colorItem.colors[colorKey] ? 'selected' : ''} key={colorKey}> - {selectedColor === colorItem.colors[colorKey] && - copyToClipboard(`rgb(${rgb.red},${rgb.green},${rgb.blue})`)}> - - rgb  - {`${rgb.red},${rgb.green},${rgb.blue}`} - - - - copyToClipboard(selectedColor)}> - - # - {selectedColor.slice(1)} - - - - } + handlerSetColor(colorItem.colors[colorKey], colorItem, colorKey)} + color={colorItem.colors[colorKey]} + colorText={colorText} + className={color === colorItem.colors[colorKey] ? 'selected' : ''} + key={colorKey} + > + {color === colorItem.colors[colorKey] && direction && ( + + copyToClipboard(`rgb(${rgb.red},${rgb.green},${rgb.blue})`)} + > + + rgb  + {`${rgb.red},${rgb.green},${rgb.blue}`} + + + + copyToClipboard(color)} + > + + # + {color.slice(1)} + + + + + )} {colorKey} ))} - + - - - - + + + + - + ); -} - -// {colorsKeys.map((colorKey) => { -// {colorKey} -// })} \ No newline at end of file +}; diff --git a/website/plasma-website/components/colors/GradientScroll.tsx b/website/plasma-website/components/colors/GradientScroll.tsx index b80743b9d4..ebead12190 100644 --- a/website/plasma-website/components/colors/GradientScroll.tsx +++ b/website/plasma-website/components/colors/GradientScroll.tsx @@ -1,50 +1,51 @@ -import React, { useState } from 'react'; +import React from 'react'; import styled from 'styled-components'; -const Container = styled.div` +const GradientScrollContainer = styled.div` position: fixed; - top: 7rem; - height: calc(100vh - 200px); + top: 7.5rem; + height: calc(100vh - 208px); left: 0; width: 4rem; padding-left: 1.875rem; - box-sizing : border-box; + box-sizing: border-box; display: flex; align-items: center; z-index: 3; `; -const ContainerScroll = styled.div` +const GradientScrollContainerScroll = styled.div` width: 2.125rem; height: 100%; position: relative; `; -const AllScroll = styled.div<{colors: string[]}>` - background: white; +const GradientScrollHeight = styled.div<{ colors: string[] }>` width: 0.25rem; height: 100%; position: absolute; top: 0; left: 0; border-radius: 0.125rem; + /* stylelint-disable */ background: linear-gradient( 180deg, - ${({colors}) => colors.map((color: string, index: number) => `${color} ${(100 / colors.length) * index}%`).join(',')} + ${({ colors }) => + colors.map((color: string, index: number) => `${color} ${(100 / colors.length) * index}%`).join(',')} ); + /* stylelint-enable */ `; -const Scroll = styled.div<{height: number, top: number}>` - background: rgba(255,255,255, 0.56); +const GradientScrollScroll = styled.div<{ height: number; top: number }>` + background: rgba(255, 255, 255, 0.56); width: 0.125rem; - height: ${({height}) => height}px; + height: ${({ height }) => height}px; position: absolute; - top: ${({top}) => top}px; + top: ${({ top }) => top}px; right: 0; border-radius: 0.125rem; `; - -const TopText = styled.div` +const GradientScrollTopText = styled.div` top: -2rem; font-size: 0.75rem; left: 100%; @@ -52,7 +53,7 @@ const TopText = styled.div` opacity: 0.8; `; -const BottomText = styled.div` +const GradientScrollBottomText = styled.div` bottom: -2rem; font-size: 0.75rem; left: 100%; @@ -60,23 +61,25 @@ const BottomText = styled.div` opacity: 0.8; `; -export const GradientScroll: React.FC<{ hsl: number[], colors: string[], scrollHeight: number, scrollTop: number, height: number }> = ({hsl, colors, scrollHeight, scrollTop, height}) => { - const heightAllScroll = height - 200; +export const GradientScroll: React.FC<{ + hsl: number[]; + colors: string[]; + scrollHeight: number; + scrollTop: number; + height: number; +}> = ({ hsl, colors, scrollHeight, scrollTop, height }) => { + const heightAllScroll = height - 208; const heightScroll = heightAllScroll / (scrollHeight / height); const topScroll = heightAllScroll * (scrollTop / scrollHeight); return ( - - - - H:{hsl[0]} - - - - - H:{hsl[hsl.length - 1]} - - - + + + H:{hsl[0]} + + + H:{hsl[hsl.length - 1]} + + ); -}; \ No newline at end of file +}; diff --git a/website/plasma-website/components/colors/Header.tsx b/website/plasma-website/components/colors/Header.tsx index bdb987745a..7ff192dcc3 100644 --- a/website/plasma-website/components/colors/Header.tsx +++ b/website/plasma-website/components/colors/Header.tsx @@ -1,39 +1,36 @@ import React from 'react'; import styled from 'styled-components'; -import { IconArrowLeft } from '@salutejs/plasma-icons'; -const Text = styled.div` - font-size: 1rem; - color: #FFFFFF; - opacity: 0.7; -`; - -const HeaderWrapper = styled.div` +const HeaderWrapper = styled.div` display: flex; top: 2rem; left: 1.625rem; gap: 1.75rem; position: fixed; align-items: center; - z-index: 100; cursor: pointer; z-index: 99999; - &:hover .hoverHeader{ + &:hover .hoverHeader { opacity: 1; } `; -const TextBold = styled(Text)` - font-weight: 700; +const HeaderText = styled.div` + font-size: 1rem; + color: rgba(255, 255, 255, 1); + opacity: 0.7; +`; +const HeaderTextBold = styled(HeaderText)` + font-weight: var(--plasma-typo-headline1-font-weight); opacity: 1; `; -export const Header:React.FC<{text?: string, onClose?: () => void}> = ({text, onClose}) => { +export const Header: React.FC<{ text?: string; onClose?: () => void }> = ({ text, onClose }) => { return ( onClose?.()}> - - {text} + + {text} ); -} \ No newline at end of file +}; diff --git a/website/plasma-website/components/colors/Pallete.tsx b/website/plasma-website/components/colors/Pallete.tsx index b78304e76e..5fd5661411 100644 --- a/website/plasma-website/components/colors/Pallete.tsx +++ b/website/plasma-website/components/colors/Pallete.tsx @@ -1,24 +1,26 @@ import { general } from '@salutejs/plasma-colors'; import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import styled from 'styled-components'; +import _ from 'lodash'; +import { useRouter } from 'next/router'; +import { ContrastRatioChecker } from 'contrast-ratio-checker'; + +import { hexToHSL } from '../../utils'; import { Header } from './Header'; import { PalleteItem } from './PalleteItem'; -import type { colorItem } from './PalleteItem'; +import type { colorItemType } from './PalleteItem'; import { Color } from './Color'; import { GradientScroll } from './GradientScroll'; -import _ from 'lodash'; -import { useRouter } from 'next/router'; -import { hexToHSL } from '../../utils'; -const StyledWrapper = styled.div` +const PaletteWrapper = styled.div` width: 100%; height: 100vh; overflow-y: scroll; padding: 2px; box-sizing: border-box; `; -const StyledColors = styled.div` +const PaletteColors = styled.div` width: 100%; height: auto; display: flex; @@ -29,21 +31,21 @@ const StyledColors = styled.div` const useReactPath = () => { const [path, setPath] = React.useState(''); const listenToPopstate = () => { - const winPath = window.location.href; - setPath(winPath); + const winPath = window.location.href; + setPath(winPath); }; React.useEffect(() => { - window.addEventListener("popstate", listenToPopstate); - return () => { - window.removeEventListener("popstate", listenToPopstate); - }; + window.addEventListener('popstate', listenToPopstate); + return () => { + window.removeEventListener('popstate', listenToPopstate); + }; }, []); return path; }; export const Pallete: React.FC = () => { - const [scrollPosition, setScrollPosition] = useState({scrollTop: 0, scrollHeight: 0, clientHeight: 0}); - const [selectColorItem, setSelectColorItem] = useState(null); + const [scrollPosition, setScrollPosition] = useState({ scrollTop: 0, scrollHeight: 0, clientHeight: 0 }); + const [selectColorItem, setSelectColorItem] = useState(null); const [selectColor, setSelectColor] = useState(null); const [selectCode, setSelectCode] = useState(null); @@ -52,112 +54,110 @@ export const Pallete: React.FC = () => { const scrollRef = useRef(null); - const handlerSetColorPage = (color?: string, colorItem?: colorItem, code?: string) => { + const handlerSetColorPage = (color?: string, colorItem?: colorItemType, code?: string) => { setSelectColor(color); setSelectColorItem(colorItem); setSelectCode(code); - router.push({pathname: '/colors', query: { - color: colorItem?.name, - code: code - }}); - } + router.push({ + pathname: '/colors', + query: { + color: colorItem?.name, + code, + }, + }); + }; - const handlerOnClose = () => { - if(selectColorItem && selectColor){ + const handlerOnClose = () => { + if (selectColorItem && selectColor) { setSelectColorItem(null); setSelectColor(null); setSelectCode(null); - router.push({pathname: '/colors', query: {}}); - }else{ - router.push({pathname: '/'}); - }; - } + router.push({ pathname: '/colors', query: {} }); + } else { + router.push({ pathname: '/' }); + } + }; - const handleScroll = () => { + const handlerScroll = () => { if (scrollRef.current) { const { scrollTop, scrollHeight, clientHeight } = scrollRef.current; - setScrollPosition({scrollTop, scrollHeight, clientHeight}); + setScrollPosition({ scrollTop, scrollHeight, clientHeight }); } - }; - - const allColors = _.omit(general,['gray', 'coolGray']); - - const colors = Object.keys(allColors).map((key) => ({ - name: key.charAt(0).toUpperCase() + key.slice(1), - // @ts-ignore - colors: _.omit(allColors[key], '50'), - // @ts-ignore - h: hexToHSL(allColors[key][600])[0], - })).sort((a,b) => { - return a.h - b.h; - }); - - const headerText = selectColorItem ? `${selectColorItem?.name} ${selectCode}` : `Палитра`; - const colorsForGradiend = colors.map((color) => (color.colors[500])); - const colorsHSL = colors.map((color) => (color.h)); - - // const setPage = () => { - // const urlParams = new URLSearchParams(window.location.search); - // const color = urlParams.get('color'); - // const code = urlParams.get('code'); - - // if(code && color){ - // const colorItemQuery = colors.find((colorItem) => colorItem.name.toLowerCase() == color.toLowerCase()); - // if(colorItemQuery){handlerSetColorPage(colorItemQuery.colors[code], colorItemQuery, code)}; - // }else{ - // router.push({pathname: '/colors', query: {}}); - // } - // } - useLayoutEffect(() => { - const urlParams = new URLSearchParams(window.location.search); - const color = urlParams.get('color'); - const code = urlParams.get('code'); - - if(code && color){ - const colorItemQuery = colors.find((colorItem) => colorItem.name.toLowerCase() == color.toLowerCase()); - if(colorItemQuery){handlerSetColorPage(colorItemQuery.colors[code], colorItemQuery, code)}; - }else{ - setSelectColorItem(null); - setSelectColor(null); - setSelectCode(null); + }; - router.push({pathname: '/colors', query: {}}); - } - }, []); + const checker = new ContrastRatioChecker(); - useEffect(() => { + const allColors: { + [key: string]: { + [key: string]: string; + }; + } = _.omit(general, ['gray', 'coolGray']); + + const colors = Object.keys(allColors) + .map((key) => ({ + name: key.charAt(0).toUpperCase() + key.slice(1), + colors: _.omit(allColors[key], '50'), + textColor: Object.keys(allColors[key]).map((colorKey) => { + return Math.round(checker.getContrastRatioByHex(allColors[key][colorKey], '#FFFFFF') * 100) / 100 > 2; + }), + h: hexToHSL(allColors[key][600])[0], + })) + .sort((a, b) => { + return a.h - b.h; + }); + + const headerText = selectColorItem ? `${selectColorItem?.name} ${selectCode}` : 'Палитра'; + const colorsForGradiend = colors.map((color) => color.colors[500]); + const colorsHSL = colors.map((color) => color.h); + + const setPage = () => { const urlParams = new URLSearchParams(window.location.search); const color = urlParams.get('color'); const code = urlParams.get('code'); - if(code && color){ - const colorItemQuery = colors.find((colorItem) => colorItem.name.toLowerCase() == color.toLowerCase()); - if(colorItemQuery){ - handlerSetColorPage(colorItemQuery.colors[code], colorItemQuery, code) + if (code && color) { + const colorItemQuery = colors.find((colorItem) => colorItem.name.toLowerCase() === color.toLowerCase()); + if (colorItemQuery) { + handlerSetColorPage(colorItemQuery.colors[code], colorItemQuery, code); } - }else{ + } else { setSelectColorItem(null); setSelectColor(null); setSelectCode(null); - router.push({pathname: '/colors', query: {}}); + router.push({ pathname: '/colors', query: {} }); } + }; + + useEffect(() => { + setPage(); + handlerScroll(); }, [path]); + useLayoutEffect(() => { + setPage(); + }, []); + return ( - +
- - + + {colors.map((color, index) => ( ))} - - { (selectColor && selectColorItem )&& ( - + + {selectColor && selectColorItem && ( + )} - + ); }; diff --git a/website/plasma-website/components/colors/PalleteItem.tsx b/website/plasma-website/components/colors/PalleteItem.tsx index 4da20fda33..451f174657 100644 --- a/website/plasma-website/components/colors/PalleteItem.tsx +++ b/website/plasma-website/components/colors/PalleteItem.tsx @@ -1,17 +1,35 @@ import React, { useState } from 'react'; import styled from 'styled-components'; -export type colorItem = { +export type colorItemType = { colors: { [key in number | string]: string; }; + textColor: boolean[]; name: string; h: number; }; const classes = { - active: 'palette-active' -} + active: 'palette-active', +}; + +const StyledColorItem = styled.div<{ colors: colorItemType['colors'] }>` + /* stylelint-disable */ + background: linear-gradient( + 90deg, + ${({ colors }) => colors?.[1000]} 5%, + ${({ colors }) => colors?.[800]} 30%, + ${({ colors }) => colors?.[500]} 50%, + ${({ colors }) => colors?.[250]} 70%, + ${({ colors }) => colors?.[100]} 95% + ); + /* stylelint-enable */ + width: 100%; + height: 13.125rem; + border-radius: 0.5rem; + position: relative; +`; const StyledMask = styled.div` display: flex; @@ -26,14 +44,14 @@ const StyledMask = styled.div` visibility: hidden; transition: opacity 1s, visibility 0s linear 1s; - &.${classes.active}{ + &.${classes.active} { opacity: 1; visibility: visible; transition-delay: 0s; } `; -const StyledMaskItem = styled.div<{number: string | number}>` +const StyledMaskItem = styled.div<{ color: string }>` height: 100%; width: 100%; overflow: hidden; @@ -41,15 +59,17 @@ const StyledMaskItem = styled.div<{number: string | number}>` display: flex; align-items: flex-end; box-sizing: border-box; - padding-bottom: 1rem; - padding-left: 1rem; + padding-bottom: 0.125rem; + padding-left: 0.5rem; color: rgba(0, 0, 0, 0); transition: 0.2s; + font-size: 0.75rem; + font-weight: var(--plasma-typo-body1-font-weight); &::before { content: ''; position: absolute; - inset: -0.0625rem; + inset: -0.062rem; box-shadow: 0; border-radius: 0rem; box-sizing: border-box; @@ -59,27 +79,26 @@ const StyledMaskItem = styled.div<{number: string | number}>` transition: ease-in 0.3s; } - &.${classes.active}{ + &.${classes.active} { transition: 0.2s; - &:hover{ - color: ${({number}) => Number(number) > 500 ? 'white' : 'black'}; - opacity: 0.56; + &:hover { + color: ${({ color }) => color}; transition: 0.2s; } &::before { - box-shadow: 0rem 0rem 0 1rem #000; + box-shadow: 0rem 0rem 0 1rem rgba(0, 0, 0, 1); border-radius: 0.5rem; - border-left: 0.0625rem solid black; - border-right: 0.0625rem solid black; + border-left: 0.062rem solid rgba(0, 0, 0, 1); + border-right: 0.062rem solid rgba(0, 0, 0, 1); inset: 0; transition: ease-in 0.3s; } } `; -const StyledContent = styled.div` +const StyledContent = styled.div` position: absolute; inset: 0; padding: 2rem; @@ -92,14 +111,15 @@ const StyledContent = styled.div` const StyledText = styled.div` opacity: 0.28; font-size: 4rem; - padding: 1rem 0 1.65rem 0; - color: black; - font-weight: 400; + padding: 1rem 0 1.65rem; + color: rgba(0, 0, 0, 1); + font-weight: var(--plasma-typo-body1-font-weight); transition: 0.3; transition: opacity 0.3s, visibility 0s linear 0.3s; overflow: hidden; + font-family: var(--plasma-typo-headline1-font-family); - &.${classes.active}{ + &.${classes.active} { opacity: 1; visibility: visible; transition-delay: 0s; @@ -108,53 +128,57 @@ const StyledText = styled.div` const StyledSmall = styled.div` opacity: 0.28; - font-size: 1rem; - color: black; - font-weight: 400; + font-size: 0.75rem; + color: rgba(0, 0, 0, 1); + font-weight: var(--plasma-typo-body1-font-weight); transition: 0.3; transition: opacity 0.3s, visibility 0s linear 0.3s; overflow: hidden; margin-top: 0.2rem; - &.${classes.active}{ + &.${classes.active} { opacity: 0.56; visibility: visible; transition-delay: 0s; } `; -const StyledColorItem = styled.div<{colors: any}>` - background: linear-gradient( - 90deg, - ${({colors}) => colors?.[1000]} 5%, - ${({colors}) => colors?.[800]} 30%, - ${({colors}) => colors?.[500]} 50%, - ${({colors}) => colors?.[250]} 70%, - ${({colors}) => colors?.[100]} 95% - ); - width: 100%; - height: 13.125rem; - border-radius: 0.5rem; - position: relative; - `; - -export const PalleteItem: React.FC<{ colorItem: colorItem, handlerSetColorPage: (color?: string, colorItem?: colorItem, index?: string) => void }> = ({ colorItem, handlerSetColorPage }) => { +export const PalleteItem: React.FC<{ + colorItem: colorItemType; + handlerSetColorPage: (color?: string, colorItem?: colorItemType, index?: string) => void; +}> = ({ colorItem, handlerSetColorPage }) => { const [hover, setHover] = useState(false); const colorsKeys = Object.keys(colorItem.colors).reverse(); return ( - setHover(true)} onMouseLeave={() => setHover(false)}> + setHover(true)} + onMouseLeave={() => setHover(false)} + > - {colorsKeys.map((colorKey) => ( - {handlerSetColorPage(colorItem.colors[colorKey], colorItem, colorKey); setHover(false);}}> + {colorsKeys.map((colorKey, index) => ( + { + handlerSetColorPage(colorItem.colors[colorKey], colorItem, colorKey); + setHover(false); + }} + > {colorKey} ))} {colorItem.name} - H: {colorItem.h} + H:{colorItem.h} ); diff --git a/website/plasma-website/components/colors/TextReadble.tsx b/website/plasma-website/components/colors/TextReadble.tsx index 6ab86b2acd..b0e2ed6779 100644 --- a/website/plasma-website/components/colors/TextReadble.tsx +++ b/website/plasma-website/components/colors/TextReadble.tsx @@ -1,110 +1,118 @@ import React from 'react'; import styled from 'styled-components'; -import {ContrastRatioChecker} from 'contrast-ratio-checker'; +import { ContrastRatioChecker } from 'contrast-ratio-checker'; import { IconAttentionCircleOutline } from '@salutejs/plasma-icons'; -const justify: {[key: string]: string} = { +const justify: { [key: string]: string } = { left: 'flex-end', right: 'flex-start', }; -const columnDirection: {[key: string]: string} = { +const columnDirection: { [key: string]: string } = { top: 'column', bottom: 'column-reverse', }; -const rowDirection: {[key: string]: string} = { +const rowDirection: { [key: string]: string } = { left: 'row', right: 'row-reverse', }; -const text = { - 'AAA': 'Отлично', - 'AA': 'Нормально', - 'Poor': 'Плохо' -} - -const getWCAGIndex = (ratio: number, type: 'small' | 'lagre') => { - if(ratio > 7){ - return 'AAA'; - }else if(ratio > 4.5){ - return type === 'small' ? 'AA' : 'AAA'; - }else if(ratio > 3 && type === 'lagre'){ - return 'AA'; - }else{ - return 'Poor'; - } -} +const text = { + AAA: 'Отлично', + AA: 'Нормально', + Poor: 'Плохо', +}; -const MainWrapper = styled.div<{alignX: string}>` +const TextReadbleWrapper = styled.div<{ alignX: string }>` padding: 1rem; display: flex; align-items: center; - justify-content: ${({alignX}) => justify?.[alignX]}; + justify-content: ${({ alignX }) => justify?.[alignX]}; + transition: 400ms; `; -const TextWrapper = styled.div<{alignX: string, alignY: string}>` +const TextReadbleTextWrapper = styled.div<{ alignX: string; alignY: string }>` display: flex; - flex-direction: ${({alignY}) => columnDirection?.[alignY]}; - align-items: ${({alignX}) => justify?.[alignX]}; + flex-direction: ${({ alignY }) => columnDirection?.[alignY]}; + align-items: ${({ alignX }) => justify?.[alignX]}; gap: 0.75rem; `; -const TextSmall = styled.div<{alignX: string, score: string}>` +const TextReadbleTextSmall = styled.div<{ alignX: string; score: string }>` font-size: 0.875rem; - font-weight: 400; + font-weight: var(--plasma-typo-body1-font-weight); display: flex; align-items: center; - flex-direction: ${({alignX}) => rowDirection[alignX]}; + flex-direction: ${({ alignX }) => rowDirection[alignX]}; gap: 0.5rem; cursor: default; transition: 0.15s; + font-family: var(--plasma-typo-headline1-font-family); - &:hover{ - color: ${({score}) => score === 'Poor' ? 'red' : 'inhert'}; + &:hover { + color: ${({ score }) => (score === 'Poor' ? 'red' : 'inhert')}; transition: 0.15s; } `; -const TextLarge = styled.div<{alignX: string, score: string}>` +const TextReadbleTextLarge = styled.div<{ alignX: string; score: string }>` font-size: 2rem; - font-weight: 400; + font-weight: var(--plasma-typo-body1-font-weight); display: flex; align-items: center; gap: 0.5rem; - flex-direction: ${({alignX}) => rowDirection[alignX]}; + flex-direction: ${({ alignX }) => rowDirection[alignX]}; cursor: default; transition: 0.15s; + font-family: var(--plasma-typo-headline1-font-family); - &:hover{ - color: ${({score}) => score === 'Poor' ? 'red' : 'inhert'}; + &:hover { + color: ${({ score }) => (score === 'Poor' ? 'red' : 'inhert')}; transition: 0.15s; } `; -export const TextReadble: React.FC<{background: string, color: string, alignX: 'left' | 'right', alignY: 'top' | 'bottom'}> = ({ background, color, alignX, alignY }) => { +const getWCAGIndex = (ratio: number, type: 'small' | 'lagre') => { + if (ratio > 7) { + return 'AAA'; + } + if (ratio > 4.5) { + return type === 'small' ? 'AA' : 'AAA'; + } + if (ratio > 3 && type === 'lagre') { + return 'AA'; + } + return 'Poor'; +}; + +export const TextReadble: React.FC<{ + background: string; + color: string; + alignX: 'left' | 'right'; + alignY: 'top' | 'bottom'; +}> = ({ background, color, alignX, alignY }) => { const checker = new ContrastRatioChecker(); - + const ratio = Math.round(checker.getContrastRatioByHex(background, color) * 100) / 100; - const small = getWCAGIndex(ratio,'small'); - const large = getWCAGIndex(ratio,'lagre'); + const small = getWCAGIndex(ratio, 'small'); + const large = getWCAGIndex(ratio, 'lagre'); - const smallText = [text[small], small !== 'Poor' ? small : '', ratio]; - const lagreText = [text[large], large !== 'Poor' ? large : '', ratio]; + const smallText = [text[small], small !== 'Poor' ? small : '', ratio.toFixed(2)]; + const lagreText = [text[large], large !== 'Poor' ? large : '', ratio.toFixed(2)]; return ( - - - { - large === 'Poor' && - - } - {alignX == 'right' ? lagreText.reverse().join(' ') : lagreText.join(' ')} - - { small === 'Poor' && - } - {alignX == 'right' ? smallText.reverse().join(' ') : smallText.join(' ')} - - + + + + {large === 'Poor' && } + {alignX === 'right' ? lagreText.reverse().join(' ') : lagreText.join(' ')} + + + {small === 'Poor' && } + {alignX === 'right' ? smallText.reverse().join(' ') : smallText.join(' ')} + + + ); -} \ No newline at end of file +}; diff --git a/website/plasma-website/package-lock.json b/website/plasma-website/package-lock.json index ef0d5d33e1..eb124ef001 100644 --- a/website/plasma-website/package-lock.json +++ b/website/plasma-website/package-lock.json @@ -1,15 +1,16 @@ { "name": "@salutejs/plasma-website", - "version": "0.300.0", + "version": "0.301.0-dev.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@salutejs/plasma-website", - "version": "0.300.0", + "version": "0.301.0-dev.0", "license": "MIT", "dependencies": { - "@salutejs/plasma-b2c": "1.338.0", + "@salutejs/plasma-b2c": "1.339.0-dev.0", + "@salutejs/plasma-colors": "0.13.0", "@salutejs/plasma-icons": "1.198.0", "@salutejs/plasma-tokens": "1.81.0", "@salutejs/plasma-tokens-b2c": "0.50.0", @@ -25,6 +26,7 @@ "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@types/styled-components": "^5.1.0", + "contrast-ratio-checker": "^1.1.7", "eslint": "7.29.0", "eslint-config-next": "11.0.1", "typescript": "4.3.4" @@ -1002,13 +1004,13 @@ "dev": true }, "node_modules/@salutejs/plasma-b2c": { - "version": "1.338.0", - "resolved": "https://registry.npmjs.org/@salutejs/plasma-b2c/-/plasma-b2c-1.338.0.tgz", - "integrity": "sha512-Ks/P6BUnjFZeEDVvcPDpQ8JrL4DRZtrLX0Ng6Csi95cj/l09c2Ykk/i9p9ZIGAp0FEbn74o+A/nTSvms8bPbwQ==", + "version": "1.339.0-dev.0", + "resolved": "https://registry.npmjs.org/@salutejs/plasma-b2c/-/plasma-b2c-1.339.0-dev.0.tgz", + "integrity": "sha512-IkxCuY64gDp0G9rcvhyDUDhXmfg3MaGs0kgQ3ldnD1k+IG5efgtqgZf+4rWDMjkBL7q06rpILdKw25r7G0MBsA==", "dependencies": { "@salutejs/plasma-core": "1.160.0", "@salutejs/plasma-hope": "1.285.0", - "@salutejs/plasma-new-hope": "0.93.0", + "@salutejs/plasma-new-hope": "0.94.0-dev.0", "@salutejs/plasma-tokens-b2c": "0.50.0", "@salutejs/plasma-tokens-web": "1.55.0", "@salutejs/plasma-typo": "0.40.0" @@ -1075,14 +1077,15 @@ } }, "node_modules/@salutejs/plasma-new-hope": { - "version": "0.93.0", - "resolved": "https://registry.npmjs.org/@salutejs/plasma-new-hope/-/plasma-new-hope-0.93.0.tgz", - "integrity": "sha512-yGzNS6SR1u8WSXRIoPS4zwVRow5R/fGyKMry5pDSbQ6GPNJnLvFKVbGff6OhNIL7Tgt3XAYAt7qCN6Sw8s5tug==", + "version": "0.94.0-dev.0", + "resolved": "https://registry.npmjs.org/@salutejs/plasma-new-hope/-/plasma-new-hope-0.94.0-dev.0.tgz", + "integrity": "sha512-a5VkZEPzhqLgRVTKcsuFeDpfThjAWj/T16QRuUDvgOiXED4P6Q2jiRgfkbpH0eLrttOKCPWi+AhzeiaoUl9HxQ==", "dependencies": { "@linaria/core": "5.0.2", "@linaria/react": "5.0.3", "@popperjs/core": "2.11.8", "@salutejs/plasma-core": "1.160.0", + "dayjs": "1.11.11", "focus-visible": "5.2.0", "lodash.throttle": "4.1.1", "react-draggable": "4.4.3", @@ -1755,6 +1758,11 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "node_modules/contrast-ratio-checker": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/contrast-ratio-checker/-/contrast-ratio-checker-1.1.7.tgz", + "integrity": "sha512-uTWkg4c2XKuHS+wpcdvCltwV9pGVD+jTNBxzehzIbs/h9hAFHMXm/BXacgOieYoOfLstGqsJishdfjJmgTso0A==" + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -1816,6 +1824,11 @@ "integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==", "dev": true }, + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1876,9 +1889,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.812", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz", - "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==" + "version": "1.4.815", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.815.tgz", + "integrity": "sha512-OvpTT2ItpOXJL7IGcYakRjHCt8L5GrrN/wHCQsRB4PQa1X9fe+X9oen245mIId7s14xvArCGSTIq644yPUKKLg==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -4057,6 +4070,12 @@ "html-element-attributes": "^1.0.0" } }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "peer": true + }, "node_modules/react-popper": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", @@ -4861,12 +4880,6 @@ "loose-envify": "^1.0.0" } }, - "node_modules/wcag-color": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/wcag-color/-/wcag-color-1.1.1.tgz", - "integrity": "sha512-KRez+YYOx7AGoQ6+Izu3YjNsISYAC+F/g0hJ+eNaaA8taeLbEkptkgA46SM9ioXxz/2KTjJpQqAhOwAQVwaTEQ==", - "dev": true - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5607,13 +5620,13 @@ "dev": true }, "@salutejs/plasma-b2c": { - "version": "1.338.0", - "resolved": "https://registry.npmjs.org/@salutejs/plasma-b2c/-/plasma-b2c-1.338.0.tgz", - "integrity": "sha512-Ks/P6BUnjFZeEDVvcPDpQ8JrL4DRZtrLX0Ng6Csi95cj/l09c2Ykk/i9p9ZIGAp0FEbn74o+A/nTSvms8bPbwQ==", + "version": "1.339.0-dev.0", + "resolved": "https://registry.npmjs.org/@salutejs/plasma-b2c/-/plasma-b2c-1.339.0-dev.0.tgz", + "integrity": "sha512-IkxCuY64gDp0G9rcvhyDUDhXmfg3MaGs0kgQ3ldnD1k+IG5efgtqgZf+4rWDMjkBL7q06rpILdKw25r7G0MBsA==", "requires": { "@salutejs/plasma-core": "1.160.0", "@salutejs/plasma-hope": "1.285.0", - "@salutejs/plasma-new-hope": "0.93.0", + "@salutejs/plasma-new-hope": "0.94.0-dev.0", "@salutejs/plasma-tokens-b2c": "0.50.0", "@salutejs/plasma-tokens-web": "1.55.0", "@salutejs/plasma-typo": "0.40.0" @@ -5655,17 +5668,19 @@ "@salutejs/plasma-icons": { "version": "1.198.0", "resolved": "https://registry.npmjs.org/@salutejs/plasma-icons/-/plasma-icons-1.198.0.tgz", - "integrity": "sha512-0OdHWq12uVhIGWKiHD7qyHEMNntphl1YOnuLwls83oE5nutlxeFHm9dWsLRY50jJZJN+lcpAe86pueb1Ie5JgA==" + "integrity": "sha512-0OdHWq12uVhIGWKiHD7qyHEMNntphl1YOnuLwls83oE5nutlxeFHm9dWsLRY50jJZJN+lcpAe86pueb1Ie5JgA==", + "requires": {} }, "@salutejs/plasma-new-hope": { - "version": "0.93.0", - "resolved": "https://registry.npmjs.org/@salutejs/plasma-new-hope/-/plasma-new-hope-0.93.0.tgz", - "integrity": "sha512-yGzNS6SR1u8WSXRIoPS4zwVRow5R/fGyKMry5pDSbQ6GPNJnLvFKVbGff6OhNIL7Tgt3XAYAt7qCN6Sw8s5tug==", + "version": "0.94.0-dev.0", + "resolved": "https://registry.npmjs.org/@salutejs/plasma-new-hope/-/plasma-new-hope-0.94.0-dev.0.tgz", + "integrity": "sha512-a5VkZEPzhqLgRVTKcsuFeDpfThjAWj/T16QRuUDvgOiXED4P6Q2jiRgfkbpH0eLrttOKCPWi+AhzeiaoUl9HxQ==", "requires": { "@linaria/core": "5.0.2", "@linaria/react": "5.0.3", "@popperjs/core": "2.11.8", "@salutejs/plasma-core": "1.160.0", + "dayjs": "1.11.11", "focus-visible": "5.2.0", "lodash.throttle": "4.1.1", "react-draggable": "4.4.3", @@ -5681,14 +5696,16 @@ "storeon": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/storeon/-/storeon-3.1.5.tgz", - "integrity": "sha512-VuW4GQr3LGQr+gqscqsOz2c9asK9N+B+8+sWs7Pj4OqU7bngYIqsPF3IYpkbmccKNWjs7wwxUAlR+gtL9cEMEg==" + "integrity": "sha512-VuW4GQr3LGQr+gqscqsOz2c9asK9N+B+8+sWs7Pj4OqU7bngYIqsPF3IYpkbmccKNWjs7wwxUAlR+gtL9cEMEg==", + "requires": {} } } }, "@salutejs/plasma-tokens": { "version": "1.81.0", "resolved": "https://registry.npmjs.org/@salutejs/plasma-tokens/-/plasma-tokens-1.81.0.tgz", - "integrity": "sha512-IK9RK3eC4hIES9+bZ3lzq5x0M0vyX7zpsWmIYUIx2PIE8j/E7heQvqJQAW6d3O5RtpgKFoyDomeVX2nr78ffdA==" + "integrity": "sha512-IK9RK3eC4hIES9+bZ3lzq5x0M0vyX7zpsWmIYUIx2PIE8j/E7heQvqJQAW6d3O5RtpgKFoyDomeVX2nr78ffdA==", + "requires": {} }, "@salutejs/plasma-tokens-b2c": { "version": "0.50.0", @@ -5703,7 +5720,8 @@ "@salutejs/plasma-typo": { "version": "0.40.0", "resolved": "https://registry.npmjs.org/@salutejs/plasma-typo/-/plasma-typo-0.40.0.tgz", - "integrity": "sha512-wjIJwHb/N5wFyTwTKt4bimt0UpM0/TS3ZsKtJVBS5foqxxJFgv32Ma75RCnnqol38M+KHDa6Lrnu2po0jiicow==" + "integrity": "sha512-wjIJwHb/N5wFyTwTKt4bimt0UpM0/TS3ZsKtJVBS5foqxxJFgv32Ma75RCnnqol38M+KHDa6Lrnu2po0jiicow==", + "requires": {} }, "@swc/helpers": { "version": "0.4.11", @@ -5903,7 +5921,8 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "requires": {} }, "ajv": { "version": "6.12.6", @@ -6142,6 +6161,11 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "contrast-ratio-checker": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/contrast-ratio-checker/-/contrast-ratio-checker-1.1.7.tgz", + "integrity": "sha512-uTWkg4c2XKuHS+wpcdvCltwV9pGVD+jTNBxzehzIbs/h9hAFHMXm/BXacgOieYoOfLstGqsJishdfjJmgTso0A==" + }, "convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -6191,6 +6215,11 @@ "integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==", "dev": true }, + "dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -6239,9 +6268,9 @@ } }, "electron-to-chromium": { - "version": "1.4.812", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz", - "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==" + "version": "1.4.815", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.815.tgz", + "integrity": "sha512-OvpTT2ItpOXJL7IGcYakRjHCt8L5GrrN/wHCQsRB4PQa1X9fe+X9oen245mIId7s14xvArCGSTIq644yPUKKLg==" }, "emoji-regex": { "version": "8.0.0", @@ -6737,7 +6766,8 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", - "dev": true + "dev": true, + "requires": {} }, "eslint-scope": { "version": "5.1.1", @@ -7861,6 +7891,12 @@ "html-element-attributes": "^1.0.0" } }, + "react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "peer": true + }, "react-popper": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", @@ -8164,7 +8200,8 @@ "storeon": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/storeon/-/storeon-3.1.4.tgz", - "integrity": "sha512-GUSyCevVP00T5b5/Z05ZGkrJFh4IbXjCAl+R27pBslamFLS/qSxJoSwYIGbIZOjujRAgUiWIzPDZP6Ma3vSR9Q==" + "integrity": "sha512-GUSyCevVP00T5b5/Z05ZGkrJFh4IbXjCAl+R27pBslamFLS/qSxJoSwYIGbIZOjujRAgUiWIzPDZP6Ma3vSR9Q==", + "requires": {} }, "string-width": { "version": "4.2.2", @@ -8254,7 +8291,8 @@ "styled-jsx": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz", - "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==" + "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==", + "requires": {} }, "supports-color": { "version": "5.5.0", @@ -8408,7 +8446,8 @@ "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} }, "v8-compile-cache": { "version": "2.3.0", @@ -8434,12 +8473,6 @@ "loose-envify": "^1.0.0" } }, - "wcag-color": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/wcag-color/-/wcag-color-1.1.1.tgz", - "integrity": "sha512-KRez+YYOx7AGoQ6+Izu3YjNsISYAC+F/g0hJ+eNaaA8taeLbEkptkgA46SM9ioXxz/2KTjJpQqAhOwAQVwaTEQ==", - "dev": true - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/website/plasma-website/utils/hexToHSL.ts b/website/plasma-website/utils/hexToHSL.ts index 64d42dbe52..9fd3f3bbd7 100644 --- a/website/plasma-website/utils/hexToHSL.ts +++ b/website/plasma-website/utils/hexToHSL.ts @@ -5,28 +5,41 @@ export const hexToHSL = (hex: string): number[] => { let g = parseInt(result?.[2] ?? '0', 16); let b = parseInt(result?.[3] ?? '0', 16); - r /= 255, g /= 255, b /= 255; - const max = Math.max(r, g, b), min = Math.min(r, g, b); - let h, s, l = (max + min) / 2; + r /= 255; + g /= 255; + b /= 255; + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + let h; + let s; + let l = (max + min) / 2; - if(max == min){ - h = s = 0; // achromatic + if (max === min) { + s = 0; + h = s; } else { const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch(max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + // no default } h = (h ?? 0) / 6; } - s = s*100; + s *= 100; s = Math.round(s); - l = l*100; + l *= 100; l = Math.round(l); - h = Math.round(360*h); + h = Math.round(360 * h); - return([h, s, l]); -} \ No newline at end of file + return [h, s, l]; +}; diff --git a/website/plasma-website/utils/hexToRGB.ts b/website/plasma-website/utils/hexToRGB.ts index c4fac38145..ad7b1777d8 100644 --- a/website/plasma-website/utils/hexToRGB.ts +++ b/website/plasma-website/utils/hexToRGB.ts @@ -1,82 +1,79 @@ export interface IRgb { - red: number - green: number - blue: number + red?: number; + green?: number; + blue?: number; } -export const isValidHex = (hex: string): Boolean => { +export const isValidHex = (hex: string): boolean => { try { - const hexRegExp = /^#(([0-9a-f]{3})|([0-9a-f]{6}))$/gi + const hexRegExp = /^#(([0-9a-f]{3})|([0-9a-f]{6}))$/gi; - return hexRegExp.test(hex) + return hexRegExp.test(hex); } catch (err) { - throw Error(`isValidHex failed. ${err}`) + throw Error(`isValidHex failed. ${err}`); } -} +}; export const getFullHex = (hex: string): string => { try { - if (hex.length === 6) return hex + if (hex.length === 6) return hex; return hex - .split("") + .split('') .map((char) => `${char}${char}`) - .join("") + .join(''); } catch (err) { - throw Error(`getFullHex failed. ${err}`) + throw Error(`getFullHex failed. ${err}`); } -} +}; -export const separateStringPerCharGroup = ( - string: string, - groupBy: number -): string[] | null => { +export const separateStringPerCharGroup = (string: string, groupBy: number): string[] | null => { try { - const regExp = new RegExp(`.{1,${groupBy}}`, "g") + const regExp = new RegExp(`.{1,${groupBy}}`, 'g'); - return string.match(regExp) + return string.match(regExp); } catch (err) { - throw Error(`separateStringPerCharGroup failed. ${err}`) + throw Error(`separateStringPerCharGroup failed. ${err}`); } -} +}; export const convertHexToRgb = (hex: string): IRgb => { try { if (!isValidHex(hex)) { - throw Error("Invalid hexadecimal string") + throw Error('Invalid hexadecimal string'); } - const hexadecimal = hex.slice(1) + const hexadecimal = hex.slice(1); - const fullHex = getFullHex(hexadecimal) + const fullHex = getFullHex(hexadecimal); - const hexParts: any = separateStringPerCharGroup(fullHex, 2) + const hexParts: string[] | null = separateStringPerCharGroup(fullHex, 2) ?? []; - const rgbObject = hexParts.reduce( - (prev: any, part: string, index: number) => { - const decimal = parseInt(part, 16) + const rgbObject: IRgb = hexParts.reduce((prev: IRgb, part: string, index: number): IRgb => { + const decimal = parseInt(part, 16); - switch (index) { - case 0: - prev.red = decimal + switch (index) { + case 0: + prev.red = decimal; - return prev - case 1: - prev.green = decimal + return prev; + case 1: + prev.green = decimal; - return prev + return prev; - case 2: - prev.blue = decimal + case 2: + prev.blue = decimal; - return prev - } - }, - {} - ) + return prev; + // no default + } - return rgbObject + return prev; + }, {}); + + return rgbObject; } catch (err) { - throw Error(`convertHexToRgb failed. ${err}`) + throw Error(`convertHexToRgb failed. ${err}`); } -} +};