diff --git a/src/common/interfaces/componentsProp.ts b/src/common/interfaces/componentsProp.ts index bcda0030d48483b9decb4416343c670a14e6f2f8..7f1a31c24c10b69f0762269bf61a829f5d7b5ac6 100644 --- a/src/common/interfaces/componentsProp.ts +++ b/src/common/interfaces/componentsProp.ts @@ -118,3 +118,5 @@ export interface ISliderOptions { color?: TThemeColor; darknessColor?: TDarkness; } + +export type TToastType = 'success' | 'info' | 'warn' | 'error'; diff --git a/src/common/interfaces/componentsProps.ts b/src/common/interfaces/componentsProps.ts index 173d041bf8dfe0217432c101743530959f02ac35..cfb5109a796a4482e7537e4a9f8263a008705c72 100644 --- a/src/common/interfaces/componentsProps.ts +++ b/src/common/interfaces/componentsProps.ts @@ -19,6 +19,7 @@ import type { ISliderOptions, ITableColumn, ITreeItem, + TToastType, } from '@interfaces/componentsProp'; export interface ITableProps { @@ -288,6 +289,15 @@ export interface ITSProps { disabled?: boolean; } +export interface IToastProps { + type?: TToastType; + theme?: TThemeColor; + size?: TSize; + text?: string; + header?: string; + icon?: TIcon; +} + export interface ITagProps { value?: string; size?: TSize; diff --git a/src/components/Toast/Toast.stories.ts b/src/components/Toast/Toast.stories.ts new file mode 100644 index 0000000000000000000000000000000000000000..b63ccafeadf77e58b887f2a91cc4855dc3e693a9 --- /dev/null +++ b/src/components/Toast/Toast.stories.ts @@ -0,0 +1,59 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import Toast from './Toast.vue'; + +const meta: Meta = { + title: 'Components/Toast', + component: Toast, + tags: ['small_data'], + parameters: { + docs: { + description: { + component: 'A component is used to categorize content. Can be used with icons.', + }, + }, + }, + argTypes: { + size: { control: 'select', options: ['small', 'normal', 'large', 'huge'] }, + theme: { + control: 'select', + options: [ + 'white', + 'blue', + 'sky', + 'cyan', + 'teal', + 'green', + 'yellow', + 'orange', + 'pink', + 'fuchsia', + 'purple', + 'indigo', + 'rose', + 'red', + 'black', + ], + }, + }, + args: {}, +} satisfies Meta<typeof Toast>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Simple: Story = { + args: { + active: true, + }, +}; + +export const Small: Story = { + args: { + size: 'small', + theme: 'red', + value: 'Dangerous', + iconRight: 'Age18Icon', + }, +}; diff --git a/src/components/Toast/Toast.vue b/src/components/Toast/Toast.vue new file mode 100644 index 0000000000000000000000000000000000000000..176c1aeba5b95d311657a98a267603c8971e093b --- /dev/null +++ b/src/components/Toast/Toast.vue @@ -0,0 +1,68 @@ +<script setup lang="ts"> +import type { IToastProps } from '@interfaces/componentsProps'; +import { computed } from 'vue'; +import { convertThemeToColor } from '@helpers/common'; +import type { TToastType } from '@interfaces/componentsProp'; + +const props = withDefaults(defineProps<IToastProps>(), { + type: 'success', + text: 'This is a toast about success.', + size: 'normal', + theme: 'green', +}); + +const typeToHeader: Record<TToastType, string> = { + success: 'Success Message', + info: 'Info Message', + warn: 'Warn Message', + error: 'Error Message', +}; + +const header = computed<string>(() => props.header ?? typeToHeader[props.type]); + +const color = computed(() => convertThemeToColor(props.theme, '400')); +const whiteOrBlack = computed(() => (props.theme === 'white' ? 'black' : 'white')); +const backgroundColor = computed(() => + convertThemeToColor(props.theme === 'white' ? 'black' : props.theme === 'black' ? 'white' : props.theme, '700'), +); +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 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'; +}); +</script> + +<template> + <section class="toast-container"> + <h3 class="toast-header" :style="`font-size: calc(${fontSize} + 4px)`">{{ header }}</h3> + <p class="toast-text">{{ text }}</p> + </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); +} +.toast-header { + color: v-bind(color); + margin-bottom: 5px; +} +.toast-text { + color: v-bind(whiteOrBlack); + font-size: v-bind(fontSize); +} +</style> diff --git a/src/postponed/Cropper/Cropper.stories.ts b/src/postponed/Cropper/Cropper.stories.ts index a7ab1380ad9ac9a6763d519513e336ac65435093..da761ae6a542c27b6c8baaba7a53dd7968a85638 100644 --- a/src/postponed/Cropper/Cropper.stories.ts +++ b/src/postponed/Cropper/Cropper.stories.ts @@ -1,45 +1,45 @@ -// import type { Meta, StoryObj } from '@storybook/vue3'; -// -// import Cropper from './Cropper.vue'; -// -// const meta: Meta = { -// title: 'Components/Cropper', -// component: Cropper, -// tags: ['pick'], -// parameters: { -// docs: { -// description: { -// component: 'A component to pick color. Can be with button.', -// }, -// }, -// }, -// argTypes: { -// menuPosition: { control: 'select', options: ['top', 'right', 'bottom', 'left'] }, -// src: { control: 'text' }, -// width: { control: 'number' }, -// height: { control: 'number' }, -// }, -// } satisfies Meta<typeof Cropper>; -// -// export default meta; -// -// type Story = StoryObj<typeof meta>; -// -// export const Simple: Story = { -// args: { -// src: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQoFRQjM-wM_nXMA03AGDXgJK3VeX7vtD3ctA&s', -// }, -// }; -// -// export const Full: Story = { -// args: { -// buttonProps: { -// label: 'Pick color!', -// theme: 'red', -// textStyle: 'bold', -// }, -// -// size: 'large', -// sameButtonColor: true, -// }, -// }; +import type { Meta, StoryObj } from '@storybook/vue3'; + +import Cropper from './Cropper.vue'; + +const meta: Meta = { + title: 'Components/Cropper', + component: Cropper, + tags: ['pick'], + parameters: { + docs: { + description: { + component: 'A component to pick color. Can be with button.', + }, + }, + }, + argTypes: { + menuPosition: { control: 'select', options: ['top', 'right', 'bottom', 'left'] }, + src: { control: 'text' }, + width: { control: 'number' }, + height: { control: 'number' }, + }, +} satisfies Meta<typeof Cropper>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Simple: Story = { + args: { + src: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQoFRQjM-wM_nXMA03AGDXgJK3VeX7vtD3ctA&s', + }, +}; + +export const Full: Story = { + args: { + buttonProps: { + label: 'Pick color!', + theme: 'red', + textStyle: 'bold', + }, + + size: 'large', + sameButtonColor: true, + }, +};