diff --git a/src/App.vue b/src/App.vue index 81a1ef6a4c03886e41f85b4bdff6d982915d03a8..4f8b11a055d700dad7ebf553e5be324e56a884c8 100644 --- a/src/App.vue +++ b/src/App.vue @@ -41,7 +41,7 @@ import CompassIcon from '@icons/Mono/CompassIcon.vue'; import ConstructionWorkerIcon from '@icons/Mono/ConstructionWorkerIcon.vue'; import ContactsIcon from '@icons/Mono/ContactsIcon.vue'; import CropIcon from '@icons/Mono/CropIcon.vue'; -import CrossCircleIcon from '@icons/Mono/CrossCircleIcon.vue'; +import CrossRoundFilledIcon from '@icons/Mono/CrossRoundFilledIcon.vue'; import CrossIcon from '@icons/Mono/CrossIcon.vue'; import CubeIcon from '@icons/Mono/CubeIcon.vue'; import CupIcon from '@icons/Mono/CupIcon.vue'; @@ -119,6 +119,9 @@ import CornerLeftBottomIcon from '@icons/Mono/CornerLeftBottomIcon.vue'; import CornerLeftTopIcon from '@icons/Mono/CornerLeftTopIcon.vue'; import CornerRightBottomIcon from '@icons/Mono/CornerRightBottomIcon.vue'; import CornerRightTopIcon from '@icons/Mono/CornerRightTopIcon.vue'; +import InfoIcon from '@icons/Mono/InfoIcon.vue'; +import WarningIcon from '@icons/Mono/WarningIcon.vue'; +import CrossRoundIcon from '@icons/Mono/CrossRoundIcon.vue'; const gentleIcons = { Age18Icon, @@ -174,7 +177,8 @@ const gentleIcons = { CornerRightTopIcon, CropIcon, CrossIcon, - CrossCircleIcon, + CrossRoundIcon, + CrossRoundFilledIcon, CubeIcon, CupIcon, CursorIcon, @@ -217,6 +221,7 @@ const gentleIcons = { HomeIcon, ImageIcon, ImageEditIcon, + InfoIcon, LineIcon, LineDashedIcon, LineDottedIcon, @@ -240,6 +245,7 @@ const gentleIcons = { TrashIcon, TriangleIcon, UserIcon, + WarningIcon, }; </script> diff --git a/src/common/constants/icons.ts b/src/common/constants/icons.ts index 45babbb9b036ffb0c3329dffb8f78ba510e37bc9..f44b674719304e37991cf78dae9e9bd3ee714e20 100644 --- a/src/common/constants/icons.ts +++ b/src/common/constants/icons.ts @@ -33,7 +33,7 @@ import CardsIcon from '@icons/Mono/CardsIcon.vue'; import ChartLineIcon from '@icons/Mono/ChartLineIcon.vue'; import ChartPieIcon from '@icons/Mono/ChartPieIcon.vue'; import ChatIcon from '@icons/Mono/ChatIcon.vue'; -import CrossCircleIcon from '@icons/Mono/CrossCircleIcon.vue'; +import CrossRoundFilledIcon from '@icons/Mono/CrossRoundFilledIcon.vue'; import CropIcon from '@icons/Mono/CropIcon.vue'; import ChatWritingIcon from '@icons/Mono/ChatWritingIcon.vue'; import CheckMarkIcon from '@icons/Mono/CheckMarkIcon.vue'; @@ -115,6 +115,9 @@ import CornerLeftBottomIcon from '@icons/Mono/CornerLeftBottomIcon.vue'; import CornerLeftTopIcon from '@icons/Mono/CornerLeftTopIcon.vue'; import CornerRightBottomIcon from '@icons/Mono/CornerRightBottomIcon.vue'; import CornerRightTopIcon from '@icons/Mono/CornerRightTopIcon.vue'; +import InfoIcon from '@icons/Mono/InfoIcon.vue'; +import WarningIcon from '@icons/Mono/WarningIcon.vue'; +import CrossRoundIcon from '@icons/Mono/CrossRoundIcon.vue'; export const iconsSet: Record<string, Component> = { Age18: Age18Icon, @@ -166,7 +169,8 @@ export const iconsSet: Record<string, Component> = { CornerRightTop: CornerRightTopIcon, Crop: CropIcon, Cross: CrossIcon, - CrossCircle: CrossCircleIcon, + CrossRound: CrossRoundIcon, + CrossRoundFilled: CrossRoundFilledIcon, Cube: CubeIcon, Cup: CupIcon, Cursor: CursorIcon, @@ -209,6 +213,7 @@ export const iconsSet: Record<string, Component> = { Home: HomeIcon, Image: ImageIcon, ImageEdit: ImageEditIcon, + Info: InfoIcon, Line: LineIcon, LineDashed: LineDashedIcon, LineDotted: LineDottedIcon, @@ -232,4 +237,5 @@ export const iconsSet: Record<string, Component> = { Trash: TrashIcon, Triangle: TriangleIcon, User: UserIcon, + Warning: WarningIcon, }; diff --git a/src/common/helpers/common.ts b/src/common/helpers/common.ts index d224eb38ffe4324d8db653c3ca06b7384b6431cd..e7743e9cc2996154622e019f1860ded39733a92a 100644 --- a/src/common/helpers/common.ts +++ b/src/common/helpers/common.ts @@ -1,4 +1,4 @@ -import { EThemeColor, type TDarkness, type TThemeColor } from '@interfaces/common'; +import { EThemeColor, type TDarkness, type TSize, type TThemeColor } from '@interfaces/common'; import { convert100ThemeToColor, convert200ThemeToColor, @@ -58,3 +58,10 @@ export const convertThemeToSecondaryColor = (theme: TThemeColor, darkness: TDark ? convertWhiteOrBlackToColor(theme, darkness as TDarkness) : convertThemeToColor(theme, String(100 + ((+darkness + 600) % 900))); }; + +export const getValueFromSize = (size: TSize, options: string[] | number[]) => { + if (size === 'normal') return options[1]; + if (size === 'large') return options[2]; + if (size === 'huge') return options[3]; + return options[0]; +}; diff --git a/src/common/interfaces/componentsProps.ts b/src/common/interfaces/componentsProps.ts index cfb5109a796a4482e7537e4a9f8263a008705c72..d36204b12127c94466d2c4db99666dbd66042a8b 100644 --- a/src/common/interfaces/componentsProps.ts +++ b/src/common/interfaces/componentsProps.ts @@ -296,6 +296,9 @@ export interface IToastProps { text?: string; header?: string; icon?: TIcon; + width?: string; + position?: TExpandedPosition; + static?: boolean; } export interface ITagProps { diff --git a/src/components/Carousel/Carousel.vue b/src/components/Carousel/Carousel.vue index e246121462c69d1434ca29884c4b422cdf20e47e..997571457f66a74cb4059a5f16d2e145df5c3f20 100644 --- a/src/components/Carousel/Carousel.vue +++ b/src/components/Carousel/Carousel.vue @@ -2,7 +2,7 @@ import type { ICarouselProps } from '@interfaces/componentsProps'; import CarouselButtonContainer from '@components/Carousel/CarouselButtonContainer.vue'; import { computed, ref } from 'vue'; -import { convertThemeToColor, convertThemeToTextColor } from '@helpers/common'; +import { convertThemeToColor, convertThemeToTextColor, getValueFromSize } from '@helpers/common'; import ArrowLeftShortIcon from '@icons/Mono/ArrowLeftShortIcon.vue'; import ArrowRightShortIcon from '@icons/Mono/ArrowRightShortIcon.vue'; import { defaultProps, getNewValue } from './helpers'; @@ -25,22 +25,17 @@ const isStartDisabled = computed(() => (props.circular ? false : current.value = const isEndDisabled = computed(() => props.circular ? false : current.value === Math.ceil(itemsLength.value / props.perView) || !itemsLength.value, ); -const sizeCoefficient = computed(() => { - const size = props.size; - if (size === 'normal') return 1; - if (size === 'large') return 2; - if (size === 'huge') return 3; - return 0.75; -}); +const sizeCoefficient = computed(() => getValueFromSize(props.size, [0.75, 1, 2, 3])); const iconSize = computed(() => 10 * sizeCoefficient.value); const itemWidth = computed(() => `calc(${props.innerWidth} / ${props.perView}`); -const buttonSize = computed(() => { - const size = props.size; - if (size === 'normal') return 12 * sizeCoefficient.value + 'px'; - if (size === 'large') return 12 * sizeCoefficient.value + 'px'; - if (size === 'huge') return 15 * sizeCoefficient.value + 'px'; - return 9 * sizeCoefficient.value + 'px'; -}); +const buttonSize = computed(() => + getValueFromSize(props.size, [ + 9 * sizeCoefficient.value + 'px', + 12 * sizeCoefficient.value + 'px', + 12 * sizeCoefficient.value + 'px', + 15 * sizeCoefficient.value + 'px', + ]), +); const translate = computed(() => `translateX(calc(-${props.innerWidth} / ${props.perView} * ${current.value - 1}))`); </script> diff --git a/src/components/Checkbox/Checkbox.vue b/src/components/Checkbox/Checkbox.vue index eae61a0de607e8e378735852488035aa6a28491d..f2b5e971a7c4f73a28055005d96cd90493aef6c7 100644 --- a/src/components/Checkbox/Checkbox.vue +++ b/src/components/Checkbox/Checkbox.vue @@ -1,7 +1,7 @@ <script setup lang="ts"> import type { ICheckboxProps } from '@interfaces/componentsProps'; import { computed, watch } from 'vue'; -import { convertThemeToColor, convertThemeToTextColor } from '@helpers/common'; +import { convertThemeToColor, convertThemeToTextColor, getValueFromSize } from '@helpers/common'; import CheckMarkIcon from '@icons/Mono/CheckMarkIcon.vue'; const props = withDefaults(defineProps<ICheckboxProps>(), { @@ -37,20 +37,10 @@ const color = computed(() => convertThemeToColor(props.textColor, props.darkness const borderColor = computed(() => props.invalid ? 'red' : props.disabled ? '#62708c' : convertThemeToColor(props.borderColor, props.darknessBorder), ); -const elSize = computed(() => { - const size = props.size; - if (size === 'normal') return 20; - if (size === 'large') return 30; - if (size === 'huge') return 40; - return 13; -}); +const elSize = computed(() => getValueFromSize(props.size, [13, 20, 30, 40])); const gap = computed(() => { if (!props.label) return '0px'; - const size = props.size; - if (size === 'normal') return '7px'; - if (size === 'large') return '10px'; - if (size === 'huge') return '15px'; - return '5px'; + return getValueFromSize(props.size, ['5px', '7px', '10px', '15px']); }); const borderWidth = computed(() => (props.size === 'large' || props.size === 'huge' ? 2 : 1)); const borderRadius = computed(() => `${elSize.value / 7 - borderWidth.value}px`); diff --git a/src/components/ColorPicker/ColorPicker.vue b/src/components/ColorPicker/ColorPicker.vue index ee6b412db5ffc8705a17cd2ab8301a6d02b843f6..8cdaf2f2c74e492fa180e8f03b1a86d6b3469b3b 100644 --- a/src/components/ColorPicker/ColorPicker.vue +++ b/src/components/ColorPicker/ColorPicker.vue @@ -2,7 +2,7 @@ import type { IColorPickerProps } from '@interfaces/componentsProps'; import { computed, type Ref } from 'vue'; import Button from './Button.vue'; -import { convertThemeToColor, convertThemeToTextColor } from '@helpers/common'; +import { convertThemeToColor, convertThemeToTextColor, getValueFromSize } from '@helpers/common'; const props = withDefaults(defineProps<IColorPickerProps>(), { size: 'normal', @@ -10,13 +10,7 @@ const props = withDefaults(defineProps<IColorPickerProps>(), { }); const value = defineModel() as Ref<string>; -const size = computed(() => { - const size = props.size; - if (size === 'normal') return '25px'; - if (size === 'large') return '40px'; - if (size === 'huge') return '60px'; - return '15px'; -}) as Ref<string>; +const size = computed(() => getValueFromSize(props.size, ['15px', '25px', '40px', '60px'])); const borderWidth = computed(() => (props.size === 'small' ? '2px' : '3px')) as Ref<string>; const borderRadius = computed(() => `calc(${size.value} * 0.3)`); diff --git a/src/components/Paginator/Paginator.vue b/src/components/Paginator/Paginator.vue index 7e6aa4bc5c1925bcee8328f25191e7523060154c..14dfc4b7f5d8371ee866ef21e5827b3ed3f61bcc 100644 --- a/src/components/Paginator/Paginator.vue +++ b/src/components/Paginator/Paginator.vue @@ -8,7 +8,7 @@ import PaginatorItem from '@components/Paginator/PaginatorItem.vue'; import { computed, type Ref, watch } from 'vue'; import Select from '@components/Select/Select.vue'; import type { ISelectOption } from '@interfaces/componentsProp'; -import { convertThemeToColor, convertThemeToTextColor } from '@helpers/common'; +import { convertThemeToColor, convertThemeToTextColor, getValueFromSize } from '@helpers/common'; const props = withDefaults(defineProps<IPaginatorProps>(), { total: 10, @@ -45,21 +45,8 @@ const items = computed(() => { if (itemsPerView === 5) return [cur - 2, cur - 1, cur, cur + 1, cur + 2]; return initArray.value; }); -const iconSize = computed(() => { - const size = props.size; - if (size === 'normal') return '10'; - if (size === 'large') return '15'; - if (size === 'huge') return '18'; - return '7'; -}); -const fontSize = computed(() => { - if (props.fontSize) return props.fontSize; - const size = props.size; - if (size === 'normal') return '16px'; - if (size === 'large') return '26px'; - if (size === 'huge') return '32px'; - return '12px'; -}); +const iconSize = computed(() => getValueFromSize(props.size, ['7', '10', '15', '18'])); +const fontSize = computed(() => getValueFromSize(props.size, ['12px', '16px', '26px', '32px'])); const itemSize = computed(() => `${+iconSize.value * 2.5}px`); const color = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); const textColor = computed(() => convertThemeToTextColor(props.theme, props.darknessTheme)); diff --git a/src/components/ProgressBar/ProgressBar.vue b/src/components/ProgressBar/ProgressBar.vue index 4bc23be97e978f0c4936c086dca2720f0011563a..ee2cde7dc64b975cf2e9ba02032666ba8d7dedee 100644 --- a/src/components/ProgressBar/ProgressBar.vue +++ b/src/components/ProgressBar/ProgressBar.vue @@ -1,7 +1,7 @@ <script setup lang="ts"> import type { IProgressBarProps } from '@interfaces/componentsProps'; import { computed, ref, type Ref, watch } from 'vue'; -import { convertThemeToColor, convertThemeToTextColor } from '@helpers/common'; +import { convertThemeToColor, convertThemeToTextColor, getValueFromSize } from '@helpers/common'; const props = withDefaults(defineProps<IProgressBarProps>(), { value: 0, @@ -36,21 +36,8 @@ const inactiveColor = computed(() => { return convertThemeToColor(current.color, current.darknessColor); }); const textColor = computed(() => convertThemeToTextColor(props.theme, props.darknessTheme)); -const fontSize = computed(() => { - if (props.fontSize) return props.fontSize; - const size = props.size; - if (size === 'normal') return '16px'; - if (size === 'large') return '20px'; - if (size === 'huge') return '24px'; - return '12px'; -}); -const defaultHeight = computed(() => { - const size = props.size; - if (size === 'normal') return '30px'; - if (size === 'large') return '45px'; - if (size === 'huge') return '60px'; - return '15px'; -}); +const fontSize = computed(() => getValueFromSize(props.size, ['12px', '16px', '20px', '24px'])); +const defaultHeight = computed(() => getValueFromSize(props.size, ['15px', '30px', '45px', '60px'])); const isClickHold = ref<boolean>(false); diff --git a/src/components/Rating/Rating.vue b/src/components/Rating/Rating.vue index 57017ce2c7cb846e5cd002f4881f6f2b40b8d163..aef15bc6db7a064b317fcac4939aa7f5ee73dfc8 100644 --- a/src/components/Rating/Rating.vue +++ b/src/components/Rating/Rating.vue @@ -3,7 +3,7 @@ import type { IRatingProps } from '@interfaces/componentsProps'; import { computed, type Ref, ref, watch } from 'vue'; import { iconsSet } from '@/common/constants/icons'; import StarFilledIcon from '@icons/Mono/StarFilledIcon.vue'; -import { convertThemeToColor } from '@helpers/common'; +import { convertThemeToColor, getValueFromSize } from '@helpers/common'; const props = withDefaults(defineProps<IRatingProps>(), { count: 5, @@ -30,13 +30,7 @@ const onHoverIndex = ref(); const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); const offColor = computed(() => (props.offTheme ? convertThemeToColor(props.offTheme, props.darknessTheme) : null)); const themeColorOnHover = computed(() => convertThemeToColor(props.offTheme ?? props.theme, '200')); -const iconSize = computed(() => { - const size = props.size; - if (size === 'normal') return '20px'; - if (size === 'large') return '30px'; - if (size === 'huge') return '40px'; - return '10px'; -}); +const iconSize = computed(() => getValueFromSize(props.size, ['10px', '20px', '30px', '40px']) as string); const onActiveClick = (index: number) => { if (value.value > index) { value.value = index; diff --git a/src/components/Tag/Tag.vue b/src/components/Tag/Tag.vue index 1de0ac74d9dc64d9769a48d6b52367fab2e99827..2b7d31bf26775bf50bd4c858953e06077ab90f0c 100644 --- a/src/components/Tag/Tag.vue +++ b/src/components/Tag/Tag.vue @@ -1,7 +1,7 @@ <script setup lang="ts"> import type { ITagProps } from '@interfaces/componentsProps'; import { computed } from 'vue'; -import { convertThemeToColor } from '@helpers/common'; +import { convertThemeToColor, getValueFromSize } from '@helpers/common'; import { iconsSet } from '@/common/constants/icons'; const props = withDefaults(defineProps<ITagProps>(), { @@ -22,20 +22,8 @@ const backgroundColor = computed(() => const borderColor = computed(() => props.border ? convertThemeToColor(props.border, props.darknessBorder) : 'transparent', ); -const fontSize = computed(() => { - const size = props.size; - if (size === 'normal') return '16px'; - if (size === 'large') return '20px'; - if (size === 'huge') return '24px'; - return '12px'; -}); -const padding = computed(() => { - const size = props.size; - if (size === 'normal') return '5px 11px'; - if (size === 'large') return '6px 13px'; - if (size === 'huge') return '7px 16px'; - return '3px 7px'; -}); +const fontSize = computed(() => getValueFromSize(props.size, ['12px', '16px', '20px', '24px'])); +const padding = computed(() => getValueFromSize(props.size, ['3px 7px', '5px 11px', '6px 13px', '7px 16px'])); </script> <template> diff --git a/src/components/Toast/Toast.stories.ts b/src/components/Toast/Toast.stories.ts index b63ccafeadf77e58b887f2a91cc4855dc3e693a9..df07b91b6e67ced01547017b6c81b81e0219a5cc 100644 --- a/src/components/Toast/Toast.stories.ts +++ b/src/components/Toast/Toast.stories.ts @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from '@storybook/vue3'; import Toast from './Toast.vue'; +import { iconsSet } from '@/common/constants/icons'; const meta: Meta = { title: 'Components/Toast', @@ -14,7 +15,12 @@ const meta: Meta = { }, }, argTypes: { + type: { control: 'select', options: ['success', 'info', 'warn', 'error'] }, size: { control: 'select', options: ['small', 'normal', 'large', 'huge'] }, + width: { control: 'text' }, + header: { control: 'text' }, + text: { control: 'text' }, + icon: { control: 'select', options: Object.keys(iconsSet) }, theme: { control: 'select', options: [ @@ -49,11 +55,53 @@ export const Simple: Story = { }, }; +export const Info: Story = { + args: { + active: true, + type: 'info', + }, +}; + +export const Warn: Story = { + args: { + active: true, + type: 'warn', + }, +}; + +export const Error: Story = { + args: { + active: true, + type: 'error', + }, +}; + export const Small: Story = { args: { + active: true, size: 'small', - theme: 'red', - value: 'Dangerous', - iconRight: 'Age18Icon', + }, +}; + +export const Large: Story = { + args: { + active: true, + size: 'large', + width: '400px', + text: 'This is a text of large toast!', + icon: 'Award', + theme: 'sky', + }, +}; + +export const Huge: Story = { + args: { + active: true, + size: 'huge', + width: '500px', + text: 'Oh, so huge... mmm.....', + icon: 'Badge', + theme: 'purple', + header: 'Custom header', }, }; diff --git a/src/components/Toast/Toast.vue b/src/components/Toast/Toast.vue index 176c1aeba5b95d311657a98a267603c8971e093b..389cd82071ee86b305070eba3032c291aee26c22 100644 --- a/src/components/Toast/Toast.vue +++ b/src/components/Toast/Toast.vue @@ -1,16 +1,27 @@ <script setup lang="ts"> import type { IToastProps } from '@interfaces/componentsProps'; -import { computed } from 'vue'; -import { convertThemeToColor } from '@helpers/common'; +import { computed, ref } from 'vue'; +import { convertThemeToColor, getValueFromSize } from '@helpers/common'; import type { TToastType } from '@interfaces/componentsProp'; +import { iconsSet } from '@/common/constants/icons'; +import CrossIcon from '@icons/Mono/CrossIcon.vue'; +import type { TThemeColor } from '@interfaces/common'; const props = withDefaults(defineProps<IToastProps>(), { type: 'success', text: 'This is a toast about success.', size: 'normal', - theme: 'green', + width: '300px', + position: 'topRight', }); +const typeToTheme: Record<TToastType, string> = { + success: 'green', + info: 'blue', + warn: 'yellow', + error: 'red', +}; + const typeToHeader: Record<TToastType, string> = { success: 'Success Message', info: 'Info Message', @@ -18,51 +29,118 @@ const typeToHeader: Record<TToastType, string> = { error: 'Error Message', }; +const typeToIcon: Record<TToastType, string> = { + success: 'CheckMark', + info: 'Info', + warn: 'Warning', + error: 'CrossRound', +}; + +const active = ref<boolean>(false); + +const themeColor = computed<TThemeColor>(() => props.theme ?? typeToTheme[props.type]); const header = computed<string>(() => props.header ?? typeToHeader[props.type]); +const icon = computed(() => props.icon ?? typeToIcon[props.type]); -const color = computed(() => convertThemeToColor(props.theme, '400')); -const whiteOrBlack = computed(() => (props.theme === 'white' ? 'black' : 'white')); +const color = computed(() => convertThemeToColor(themeColor.value, '400')); +const whiteOrBlack = computed(() => (themeColor.value === 'white' ? 'black' : 'white')); const backgroundColor = computed(() => - convertThemeToColor(props.theme === 'white' ? 'black' : props.theme === 'black' ? 'white' : props.theme, '700'), + convertThemeToColor( + themeColor.value === 'white' ? 'black' : themeColor.value === 'black' ? 'white' : themeColor.value, + '800', + ), +); +const borderColor = computed(() => convertThemeToColor(themeColor.value, '500')); +const fontSize = computed(() => getValueFromSize(props.size, ['12px', '16px', '20px', '24px'])); +const padding = computed(() => getValueFromSize(props.size, ['7px 10px', '10px 15px', '14px 20px', '20px 30px'])); +const gap = computed(() => + props.size === 'normal' ? '10px' : props.size === 'large' || props.size === 'huge' ? '15px' : '5px', ); -const borderColor = computed(() => convertThemeToColor(props.theme, '500')); -const fontSize = computed(() => { - const size = props.size; - if (size === 'normal') return '16px'; - if (size === 'large') return '20px'; - if (size === 'huge') return '24px'; - return '12px'; +const iconSize = computed(() => fontSize.value.slice(0, -2)); +const textMargin = computed(() => { + return +iconSize.value + +gap.value.slice(0, -2) + 'px'; }); -const padding = computed(() => { - const size = props.size; - if (size === 'normal') return '5px 11px'; - if (size === 'large') return '6px 13px'; - if (size === 'huge') return '7px 16px'; - return '3px 7px'; +const positionParts = computed(() => { + const result = []; + const position = props.position.toLowerCase(); + if (position.includes('top')) result.push('top'); + if (position.includes('bottom')) result.push('bottom'); + if (position.includes('left')) result.push('left'); + if (position.includes('right')) result.push('right'); + return result; }); +const activeStyles = computed(() => { + let result = ''; + if (positionParts.value[0] === 'top') result += 'top: 0;'; + if (positionParts.value[0] === 'bottom') result += 'bottom: 0;'; + if (positionParts.value[1] === 'left') result += 'left: 0;'; + if (positionParts.value[1] === 'right') result += 'right: 0;'; + return result; +}); + +const closeToast = () => {}; </script> <template> - <section class="toast-container"> - <h3 class="toast-header" :style="`font-size: calc(${fontSize} + 4px)`">{{ header }}</h3> + <section + class="toast-container" + :style="`position: ${static ? 'relative' : 'absolute'}; + ${positionParts[0]}: ${positionParts[0] === 'top' ? '-100%' : '100%'}; + ${positionParts[1]}: ${positionParts[1] === 'left' ? '-100%' : '100%'}; + ${active ? activeStyles : null}`" + > + <h3 class="toast-header" :style="`font-size: calc(${fontSize} + 4px)`"> + <component :is="iconsSet[icon]" :color="color" :size="iconSize" /> + <span class="toast-header-text">{{ header }}</span> + </h3> <p class="toast-text">{{ text }}</p> + <CrossIcon + @click="closeToast" + class="toast-close_button" + :style="`top: ${padding.split(' ')[0]}; right: ${padding.split(' ')[1]}`" + :color="color" + :size="iconSize" + /> </section> </template> <style scoped> .toast-container { - position: absolute; padding: v-bind(padding); border: 1px solid v-bind(borderColor); border-radius: 5px; - background-color: v-bind(backgroundColor); + width: v-bind(width); + ::before { + content: ''; + position: absolute; + z-index: -1; + top: 0; + left: 0; + background-color: v-bind(backgroundColor); + width: 100%; + height: 100%; + opacity: 0.55; + border-radius: 4px; + } } .toast-header { + display: flex; + gap: v-bind(gap); color: v-bind(color); margin-bottom: 5px; } +.toast-header-text { + font-weight: 500; +} .toast-text { + margin-left: v-bind(textMargin); color: v-bind(whiteOrBlack); font-size: v-bind(fontSize); } +.toast-close_button { + background-color: transparent; + position: absolute; + cursor: pointer; + display: block; +} </style> diff --git a/src/icons/Mono/CheckMarkIcon.vue b/src/icons/Mono/CheckMarkIcon.vue index 05ab9bd0e2251521a3accab1cf8bc2257026a566..b13d20f14a6ac0a622629245eaa6ea54633d6ec3 100644 --- a/src/icons/Mono/CheckMarkIcon.vue +++ b/src/icons/Mono/CheckMarkIcon.vue @@ -15,7 +15,7 @@ defineProps<Props>(); xmlns="http://www.w3.org/2000/svg" > <path - d="M19 7.34189C18.6095 6.95136 17.9763 6.95136 17.5858 7.34189L10.3407 14.587C9.95016 14.9775 9.31699 14.9775 8.92647 14.587L6.38507 12.0456C5.99454 11.6551 5.36138 11.6551 4.97085 12.0456C4.58033 12.4361 4.58033 13.0693 4.97085 13.4598L7.51774 16C8.68969 17.1689 10.5869 17.1677 11.7574 15.9974L19 8.7561C19.3905 8.36558 19.3905 7.73241 19 7.34189Z" + d="M22.7048 4.95406C22.3143 4.56353 21.6811 4.56353 21.2906 4.95406L8.72696 17.5177C8.33643 17.9082 7.70327 17.9082 7.31274 17.5177L2.714 12.919C2.32348 12.5284 1.69031 12.5284 1.29979 12.919C0.909266 13.3095 0.909265 13.9427 1.29979 14.3332L5.90392 18.9289C7.07575 20.0986 8.97367 20.0978 10.1445 18.9271L22.7048 6.36827C23.0953 5.97775 23.0953 5.34458 22.7048 4.95406Z" :fill="color ?? '#000000'" /> </svg> diff --git a/src/icons/Mono/CrossCircleIcon.vue b/src/icons/Mono/CrossRoundFilledIcon.vue similarity index 100% rename from src/icons/Mono/CrossCircleIcon.vue rename to src/icons/Mono/CrossRoundFilledIcon.vue diff --git a/src/icons/Mono/CrossRoundIcon.vue b/src/icons/Mono/CrossRoundIcon.vue new file mode 100644 index 0000000000000000000000000000000000000000..8c14a47091e28024d89849af8ee20b9e920a6a6e --- /dev/null +++ b/src/icons/Mono/CrossRoundIcon.vue @@ -0,0 +1,23 @@ +<script setup lang="ts"> +interface Props { + color?: string; + size?: string | number; +} +defineProps<Props>(); +</script> + +<template> + <svg + :fill="color ?? '#000000'" + :width="`${size ?? 40}px`" + :height="`${size ?? 40}px`" + viewBox="0 0 32 32" + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M0 16q0 3.264 1.28 6.208t3.392 5.12 5.12 3.424 6.208 1.248 6.208-1.248 5.12-3.424 3.392-5.12 1.28-6.208-1.28-6.208-3.392-5.12-5.088-3.392-6.24-1.28q-3.264 0-6.208 1.28t-5.12 3.392-3.392 5.12-1.28 6.208zM4 16q0-3.264 1.6-6.016t4.384-4.352 6.016-1.632 6.016 1.632 4.384 4.352 1.6 6.016-1.6 6.048-4.384 4.352-6.016 1.6-6.016-1.6-4.384-4.352-1.6-6.048zM9.76 20.256q0 0.832 0.576 1.408t1.44 0.608 1.408-0.608l2.816-2.816 2.816 2.816q0.576 0.608 1.408 0.608t1.44-0.608 0.576-1.408-0.576-1.408l-2.848-2.848 2.848-2.816q0.576-0.576 0.576-1.408t-0.576-1.408-1.44-0.608-1.408 0.608l-2.816 2.816-2.816-2.816q-0.576-0.608-1.408-0.608t-1.44 0.608-0.576 1.408 0.576 1.408l2.848 2.816-2.848 2.848q-0.576 0.576-0.576 1.408z" + ></path> + </svg> +</template> + +<style scoped></style> diff --git a/src/icons/Mono/InfoIcon.vue b/src/icons/Mono/InfoIcon.vue new file mode 100644 index 0000000000000000000000000000000000000000..32ee02d7045b37e61cf625e66a4188887efe76ac --- /dev/null +++ b/src/icons/Mono/InfoIcon.vue @@ -0,0 +1,25 @@ +<script setup lang="ts"> +interface Props { + color?: string; + size?: string | number; +} +defineProps<Props>(); +</script> + +<template> + <svg + :width="`${size ?? 40}px`" + :height="`${size ?? 40}px`" + viewBox="0 0 20 20" + xmlns="http://www.w3.org/2000/svg" + fill="none" + > + <path + :fill="color ?? '#000000'" + fill-rule="evenodd" + d="M10 3a7 7 0 100 14 7 7 0 000-14zm-9 7a9 9 0 1118 0 9 9 0 01-18 0zm8-4a1 1 0 011-1h.01a1 1 0 110 2H10a1 1 0 01-1-1zm.01 8a1 1 0 102 0V9a1 1 0 10-2 0v5z" + /> + </svg> +</template> + +<style scoped></style> diff --git a/src/icons/Mono/WarningIcon.vue b/src/icons/Mono/WarningIcon.vue new file mode 100644 index 0000000000000000000000000000000000000000..f6c17b0c715e89dbc3cd0da9b6ac596309488cbc --- /dev/null +++ b/src/icons/Mono/WarningIcon.vue @@ -0,0 +1,27 @@ +<script setup lang="ts"> +interface Props { + color?: string; + size?: string | number; +} +defineProps<Props>(); +</script> + +<template> + <svg + :width="`${size ?? 40}px`" + :height="`${size ?? 40}px`" + viewBox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M12 15H12.01M12 12V9M4.98207 19H19.0179C20.5615 19 21.5233 17.3256 20.7455 15.9923L13.7276 3.96153C12.9558 2.63852 11.0442 2.63852 10.2724 3.96153L3.25452 15.9923C2.47675 17.3256 3.43849 19 4.98207 19Z" + :stroke="color ?? '#000000'" + stroke-width="2" + stroke-linecap="round" + stroke-linejoin="round" + /> + </svg> +</template> + +<style scoped></style>