From 4d9daf868a11cbb2b454e2997b8e2ea990dc193a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?= =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital> Date: Sun, 15 Dec 2024 21:42:48 +0500 Subject: [PATCH] refactor: props of components --- src/assets/components.css | 9 + src/assets/main.css | 413 +++++++++--------- src/common/helpers/colors.ts | 1 + src/common/interfaces/common.ts | 8 + src/common/interfaces/components.ts | 14 - src/common/interfaces/componentsProp.ts | 32 ++ src/common/interfaces/componentsProps.ts | 86 ++++ src/stories/components/Button/Button.vue | 41 +- src/stories/components/Divider/Divider.vue | 9 +- src/stories/components/Drawer/Drawer.vue | 36 +- src/stories/components/MenuDial/MenuDial.vue | 21 +- src/stories/components/Modal/Modal.vue | 8 +- .../SelectButton/SelectButton.stories.ts | 4 +- .../components/SelectButton/SelectButton.vue | 50 +-- .../components/ToggleSwitch/ToggleSwitch.vue | 23 +- src/stories/components/TreeList/TreeItems.vue | 30 +- .../components/TreeList/TreeList.stories.ts | 2 +- src/stories/components/TreeList/TreeList.vue | 41 +- .../ButtonStorybook.vue | 47 +- 19 files changed, 470 insertions(+), 405 deletions(-) create mode 100644 src/assets/components.css delete mode 100644 src/common/interfaces/components.ts create mode 100644 src/common/interfaces/componentsProp.ts create mode 100644 src/common/interfaces/componentsProps.ts diff --git a/src/assets/components.css b/src/assets/components.css new file mode 100644 index 0000000..3fea13c --- /dev/null +++ b/src/assets/components.css @@ -0,0 +1,9 @@ +.bold { + font-weight: bold; +} +.italic { + font-style: italic; +} +.flex-column { + flex-direction: column; +} diff --git a/src/assets/main.css b/src/assets/main.css index 274ba60..7b91d0d 100644 --- a/src/assets/main.css +++ b/src/assets/main.css @@ -1,259 +1,282 @@ +@import './components.css'; + :root { - --gray-100: #f3f4f6; - --gray-200: #e5e7eb; - --gray-300: #d1d5db; - --gray-400: #9ca3af; - --gray-500: #6b7280; - --gray-600: #4b5563; - --gray-700: #374151; - --gray-800: #1f2937; - --gray-900: #111827; - --slate-100: #f1f5f9; - --slate-200: #e2e8f0; - --slate-300: #cbd5e1; - --slate-400: #94a3b8; - --slate-500: #64748b; - --slate-600: #475569; - --slate-700: #334155; - --slate-800: #1e293b; - --slate-900: #0f172a; - --red-100: #fee2e2; - --red-200: #fecaca; - --red-300: #fca5a5; - --red-400: #f87171; - --red-500: #ef4444; - --red-600: #dc2626; - --red-700: #b91c1c; - --red-800: #991b1b; - --red-900: #7f1d1d; - --orange-100: #ffedd5; - --orange-200: #fed7aa; - --orange-300: #fdba74; - --orange-400: #fb923c; - --orange-500: #f97316; - --orange-600: #ea580c; - --orange-700: #c2410c; - --orange-800: #9a3412; - --orange-900: #7c2d12; - --amber-100: #fef3c7; - --amber-200: #fde68a; - --amber-300: #fcd34d; - --amber-400: #fbbf24; - --amber-500: #f59e0b; - --amber-600: #d97706; - --amber-700: #b45309; - --amber-800: #92400e; - --amber-900: #78350f; - --yellow-100: #fef9c3; - --yellow-200: #fef08a; - --yellow-300: #fde047; - --yellow-400: #facc15; - --yellow-500: #eab308; - --yellow-600: #ca8a04; - --yellow-700: #a16207; - --yellow-800: #854d0e; - --yellow-900: #713f12; - --lime-100: #ecfccb; - --lime-200: #d9f99d; - --lime-300: #bef264; - --lime-400: #a3e635; - --lime-500: #84cc16; - --lime-600: #65a30d; - --lime-700: #4d7c0f; - --lime-800: #3f6212; - --lime-900: #365314; - --green-100: #dcfce7; - --green-200: #bbf7d0; - --green-300: #86efac; - --green-400: #4ade80; - --green-500: #22c55e; - --green-600: #16a34a; - --green-700: #15803d; - --green-800: #166534; - --green-900: #14532d; - --teal-100: #ccfbf1; - --teal-200: #99f6e4; - --teal-300: #5eead4; - --teal-400: #2dd4bf; - --teal-500: #14b8a6; - --teal-600: #0d9488; - --teal-700: #0f766e; - --teal-800: #115e59; - --teal-900: #134e4a; - --sky-100: #e0f2fe; - --sky-200: #bae6fd; - --sky-300: #7dd3fc; - --sky-400: #38bdf8; - --sky-500: #0ea5e9; - --sky-600: #0284c7; - --sky-700: #0369a1; - --sky-800: #075985; - --sky-900: #0c4a6e; - --blue-100: #dbeafe; - --blue-200: #bfdbfe; - --blue-300: #93c5fd; - --blue-400: #60a5fa; - --blue-500: #3b82f6; - --blue-600: #2563eb; - --blue-700: #1d4ed8; - --blue-800: #1e40af; - --blue-900: #1e3a8a; - --indigo-100: #e0e7ff; - --indigo-200: #c7d2fe; - --indigo-300: #a5b4fc; - --indigo-400: #818cf8; - --indigo-500: #6366f1; - --indigo-600: #4f46e5; - --indigo-700: #4338ca; - --indigo-800: #3730a3; - --indigo-900: #312e81; - --purple-100: #f3e8ff; - --purple-200: #e9d5ff; - --purple-300: #d8b4fe; - --purple-400: #c084fc; - --purple-500: #a855f7; - --purple-600: #9333ea; - --purple-700: #7e22ce; - --purple-800: #6b21a8; - --purple-900: #581c87; - --fuchsia-100: #fae8ff; - --fuchsia-200: #f5d0fe; - --fuchsia-300: #f0abfc; - --fuchsia-400: #e879f9; - --fuchsia-500: #d946ef; - --fuchsia-600: #c026d3; - --fuchsia-700: #a21caf; - --fuchsia-800: #86198f; - --fuchsia-900: #701a75; - --pink-100: #fce7f3; - --pink-200: #fbcfe8; - --pink-300: #f9a8d4; - --pink-400: #f472b6; - --pink-500: #ec4899; - --pink-600: #db2777; - --pink-700: #be185d; - --pink-800: #9d174d; - --pink-900: #831843; - --rose-100: #ffe4e6; - --rose-200: #fecdd3; - --rose-300: #fda4af; - --rose-400: #fb7185; - --rose-500: #f43f5e; - --rose-600: #e11d48; - --rose-700: #be123c; - --rose-800: #9f1239; - --rose-900: #881337; + --gray-100: #f3f4f6; + --gray-200: #e5e7eb; + --gray-300: #d1d5db; + --gray-400: #9ca3af; + --gray-500: #6b7280; + --gray-600: #4b5563; + --gray-700: #374151; + --gray-800: #1f2937; + --gray-900: #111827; + --slate-100: #f1f5f9; + --slate-200: #e2e8f0; + --slate-300: #cbd5e1; + --slate-400: #94a3b8; + --slate-500: #64748b; + --slate-600: #475569; + --slate-700: #334155; + --slate-800: #1e293b; + --slate-900: #0f172a; + --red-100: #fee2e2; + --red-200: #fecaca; + --red-300: #fca5a5; + --red-400: #f87171; + --red-500: #ef4444; + --red-600: #dc2626; + --red-700: #b91c1c; + --red-800: #991b1b; + --red-900: #7f1d1d; + --orange-100: #ffedd5; + --orange-200: #fed7aa; + --orange-300: #fdba74; + --orange-400: #fb923c; + --orange-500: #f97316; + --orange-600: #ea580c; + --orange-700: #c2410c; + --orange-800: #9a3412; + --orange-900: #7c2d12; + --amber-100: #fef3c7; + --amber-200: #fde68a; + --amber-300: #fcd34d; + --amber-400: #fbbf24; + --amber-500: #f59e0b; + --amber-600: #d97706; + --amber-700: #b45309; + --amber-800: #92400e; + --amber-900: #78350f; + --yellow-100: #fef9c3; + --yellow-200: #fef08a; + --yellow-300: #fde047; + --yellow-400: #facc15; + --yellow-500: #eab308; + --yellow-600: #ca8a04; + --yellow-700: #a16207; + --yellow-800: #854d0e; + --yellow-900: #713f12; + --lime-100: #ecfccb; + --lime-200: #d9f99d; + --lime-300: #bef264; + --lime-400: #a3e635; + --lime-500: #84cc16; + --lime-600: #65a30d; + --lime-700: #4d7c0f; + --lime-800: #3f6212; + --lime-900: #365314; + --green-100: #dcfce7; + --green-200: #bbf7d0; + --green-300: #86efac; + --green-400: #4ade80; + --green-500: #22c55e; + --green-600: #16a34a; + --green-700: #15803d; + --green-800: #166534; + --green-900: #14532d; + --teal-100: #ccfbf1; + --teal-200: #99f6e4; + --teal-300: #5eead4; + --teal-400: #2dd4bf; + --teal-500: #14b8a6; + --teal-600: #0d9488; + --teal-700: #0f766e; + --teal-800: #115e59; + --teal-900: #134e4a; + --sky-100: #e0f2fe; + --sky-200: #bae6fd; + --sky-300: #7dd3fc; + --sky-400: #38bdf8; + --sky-500: #0ea5e9; + --sky-600: #0284c7; + --sky-700: #0369a1; + --sky-800: #075985; + --sky-900: #0c4a6e; + --blue-100: #dbeafe; + --blue-200: #bfdbfe; + --blue-300: #93c5fd; + --blue-400: #60a5fa; + --blue-500: #3b82f6; + --blue-600: #2563eb; + --blue-700: #1d4ed8; + --blue-800: #1e40af; + --blue-900: #1e3a8a; + --indigo-100: #e0e7ff; + --indigo-200: #c7d2fe; + --indigo-300: #a5b4fc; + --indigo-400: #818cf8; + --indigo-500: #6366f1; + --indigo-600: #4f46e5; + --indigo-700: #4338ca; + --indigo-800: #3730a3; + --indigo-900: #312e81; + --purple-100: #f3e8ff; + --purple-200: #e9d5ff; + --purple-300: #d8b4fe; + --purple-400: #c084fc; + --purple-500: #a855f7; + --purple-600: #9333ea; + --purple-700: #7e22ce; + --purple-800: #6b21a8; + --purple-900: #581c87; + --fuchsia-100: #fae8ff; + --fuchsia-200: #f5d0fe; + --fuchsia-300: #f0abfc; + --fuchsia-400: #e879f9; + --fuchsia-500: #d946ef; + --fuchsia-600: #c026d3; + --fuchsia-700: #a21caf; + --fuchsia-800: #86198f; + --fuchsia-900: #701a75; + --pink-100: #fce7f3; + --pink-200: #fbcfe8; + --pink-300: #f9a8d4; + --pink-400: #f472b6; + --pink-500: #ec4899; + --pink-600: #db2777; + --pink-700: #be185d; + --pink-800: #9d174d; + --pink-900: #831843; + --rose-100: #ffe4e6; + --rose-200: #fecdd3; + --rose-300: #fda4af; + --rose-400: #fb7185; + --rose-500: #f43f5e; + --rose-600: #e11d48; + --rose-700: #be123c; + --rose-800: #9f1239; + --rose-900: #881337; } body { - min-height: 100vh; - overflow-x: hidden; + min-height: 100vh; + overflow-x: hidden; } * { - font-family: Arial, serif; + font-family: Arial, serif; } #app { - min-height: 100vh; - display: flex; - flex-flow: column; + min-height: 100vh; + display: flex; + flex-flow: column; } #sheetContainer { - padding-top: 80px; + padding-top: 80px; } #app > main { - flex: 1 1 auto; + flex: 1 1 auto; } /* Reset and base styles */ * { - padding: 0; - margin: 0; - border: none; - box-sizing: border-box; + padding: 0; + margin: 0; + border: none; + box-sizing: border-box; } *, *::before, *::after { - box-sizing: border-box; - font-weight: 500; + box-sizing: border-box; + font-weight: 500; } /* Links */ -a, a:link, a:visited { - text-decoration: none; +a, +a:link, +a:visited { + text-decoration: none; } -a:hover { - text-decoration: none; +a:hover { + text-decoration: none; } /* Common */ -aside, nav, footer, header, section, main { - display: block; +aside, +nav, +footer, +header, +section, +main { + display: block; } -h1, h2, h3, h4, h5, h6, p { - font-size: inherit; - font-weight: inherit; +h1, +h2, +h3, +h4, +h5, +h6, +p { + font-size: inherit; + font-weight: inherit; } -ul, ul li { - list-style: none; +ul, +ul li { + list-style: none; } img { - vertical-align: top; + vertical-align: top; } -img, svg { - max-width: 100%; - height: auto; +img, +svg { + max-width: 100%; + height: auto; } address { - font-style: normal; + font-style: normal; } /* Form */ -input, textarea, button, select { - font-family: inherit; - font-size: inherit; - color: inherit; - background-color: transparent; +input, +textarea, +button, +select { + font-family: inherit; + font-size: inherit; + color: inherit; + background-color: transparent; } input::-ms-clear { - display: none; + display: none; } -button, input[type="submit"] { - display: inline-block; - box-shadow: none; - background-color: transparent; - background: none; - cursor: pointer; +button, +input[type='submit'] { + display: inline-block; + box-shadow: none; + background-color: transparent; + background: none; + cursor: pointer; } -input:focus, input:active, -button:focus, button:active { - outline: none; +input:focus, +input:active, +button:focus, +button:active { + outline: none; } button::-moz-focus-inner { - padding: 0; - border: 0; + padding: 0; + border: 0; } label { - cursor: pointer; + cursor: pointer; } legend { - display: block; + display: block; } input[type=file], /* FF, IE7+, chrome (except button) */ input[type=file]::-webkit-file-upload-button { - cursor: pointer; -} \ No newline at end of file + cursor: pointer; +} diff --git a/src/common/helpers/colors.ts b/src/common/helpers/colors.ts index 6711bd0..5ec5279 100644 --- a/src/common/helpers/colors.ts +++ b/src/common/helpers/colors.ts @@ -74,6 +74,7 @@ export const convert500ThemeToColor = (theme: string | undefined) => { case 'black': return '#000000'; } + return '#000000'; }; export const convert800ThemeToColor = (theme: string | undefined) => { diff --git a/src/common/interfaces/common.ts b/src/common/interfaces/common.ts index 58ed72e..4a03891 100644 --- a/src/common/interfaces/common.ts +++ b/src/common/interfaces/common.ts @@ -19,4 +19,12 @@ export type TThemeColor = export type TThemeColorNoWhite = Exclude<TThemeColor, 'white'>; +export type TSize = 'small' | 'medium' | 'large' | 'huge'; + +export type TTextStyle = 'bold' | 'italic'; + +export type TPosition = 'top' | 'right' | 'bottom' | 'left'; + +export type TBorder = 'solid' | 'dashed' | 'dotted'; + export type TIcons = keyof typeof iconsSet; diff --git a/src/common/interfaces/components.ts b/src/common/interfaces/components.ts deleted file mode 100644 index 9c101ff..0000000 --- a/src/common/interfaces/components.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { TIcons, TThemeColor } from '@interfaces/common'; - -export interface ITreeItem { - label: string; - link?: string; - linkBlank?: boolean; - color?: TThemeColor; - textStyle?: 'bold' | 'italic'; - isTriangleToColor?: boolean; - iconBefore?: TIcons; - iconAfter?: TIcons; - iconColor?: TThemeColor; - children?: ITreeItem[]; -} diff --git a/src/common/interfaces/componentsProp.ts b/src/common/interfaces/componentsProp.ts new file mode 100644 index 0000000..1f0e3c3 --- /dev/null +++ b/src/common/interfaces/componentsProp.ts @@ -0,0 +1,32 @@ +import type { TIcons, TPosition, TTextStyle, TThemeColor } from '@interfaces/common'; + +export interface ITreeItem { + label: string; + link?: string; + linkBlank?: boolean; + color?: TThemeColor; + textStyle?: TTextStyle; + isTriangleToColor?: boolean; + iconBefore?: TIcons; + iconAfter?: TIcons; + iconColor?: TThemeColor; + children?: ITreeItem[]; + isLinkClicked?: boolean; +} + +export interface ISBOption { + label: string; + value?: never; + color?: TThemeColor; + activeColor?: TThemeColor; + backgroundColor?: TThemeColor; + isLabelHidden?: boolean; + iconPosition?: TPosition; + textStyle?: TTextStyle; +} + +export interface ISliderOptions { + label: string | number; + value?: string | number; + color?: string; +} diff --git a/src/common/interfaces/componentsProps.ts b/src/common/interfaces/componentsProps.ts new file mode 100644 index 0000000..a7021a9 --- /dev/null +++ b/src/common/interfaces/componentsProps.ts @@ -0,0 +1,86 @@ +import type { + TBorder, + TIcons, + TPosition, + TSize, + TTextStyle, + TThemeColor, + TThemeColorNoWhite, +} from '@interfaces/common'; +import type { ISBOption, ISliderOptions, ITreeItem } from '@interfaces/componentsProp'; + +export interface ITLProps { + items: ITreeItem[]; + maxWidth?: number; + expand?: boolean; + theme?: TThemeColor; +} + +export interface ITIProps { + state: { + isOpen: boolean; + label: string; + }[]; + items: ITreeItem[]; + textColor: TThemeColor; + themeColor: string; +} + +export interface ISliderProps { + width?: string | number; + min?: string | number; + max?: string | number; + step?: string | number; + size?: TSize; + theme?: TThemeColor; + backgroundColor?: TThemeColor; + orientation?: 'horizontal' | 'vertical'; + isSmooth?: boolean; + options?: ISliderOptions[]; +} + +export interface IDrawerProps { + position?: TPosition; + width?: string | number; + theme?: TThemeColor; + modal?: boolean; + dismissible?: boolean; + closeIcon?: TIcons; + headerDivider?: boolean; + footerDivider?: boolean; +} + +export interface ISBProps { + options: ISBOption[]; + size?: TSize; + rounded?: boolean; + activeBackgroundColor?: TThemeColor; + border?: TThemeColor; + disabled?: boolean; +} + +export interface IButtonProps { + label?: string; + size?: TSize; + textStyle?: TTextStyle; + iconPos?: TPosition; + width?: string | number; + theme?: TThemeColor; + textColor?: TThemeColor; + border?: TThemeColor; + iconOnly?: boolean; +} + +export interface ITSProps { + size?: TSize; + theme?: TThemeColorNoWhite; + negativeTheme?: TThemeColor; + darkNegative?: boolean; + disabled?: boolean; +} + +export interface IDividerProps { + height?: number; + type?: TBorder; + color?: TThemeColor; +} diff --git a/src/stories/components/Button/Button.vue b/src/stories/components/Button/Button.vue index fd21f80..cef4d55 100644 --- a/src/stories/components/Button/Button.vue +++ b/src/stories/components/Button/Button.vue @@ -1,29 +1,17 @@ <script setup lang="ts"> import { computed } from 'vue'; -import type { TThemeColor } from '@interfaces/common'; import { convert500ThemeToColor } from '@helpers/colors'; +import type { IButtonProps } from '@interfaces/componentsProps'; + +const props = withDefaults(defineProps<IButtonProps>(), { + size: 'medium', + theme: 'white', + textColor: 'black', + iconPos: 'left', +}); -const props = withDefaults( - defineProps<{ - label?: string; - size?: 'small' | 'medium' | 'large' | 'huge'; - textStyle?: 'bold' | 'italic'; - iconPos?: 'left' | 'top' | 'right' | 'bottom'; - width?: string | number; - theme?: TThemeColor; - textColor?: TThemeColor; - border?: TThemeColor; - iconOnly?: boolean; - }>(), - { - size: 'medium', - theme: 'white', - textColor: 'black', - iconPos: 'left', - }, -); const themeColor = computed(() => convert500ThemeToColor(props.theme)); -const textColor = computed(() => convert500ThemeToColor(props.textColor)); +const textColorComputed = computed(() => convert500ThemeToColor(props.textColor)); const borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : '')); const textSize = computed(() => { switch (props.size) { @@ -64,7 +52,7 @@ const width = computed(() => (props.width ? `${props.width}px` : 'max-content')) <span :style="`background-color: ${themeColor}`" class="background"></span> <span v-if="label || !iconOnly" - :style="`color: ${textColor}; font-size: ${textSize}`" + :style="`color: ${textColorComputed}; font-size: ${textSize}`" :class="[ 'text', { @@ -125,18 +113,9 @@ const width = computed(() => (props.width ? `${props.width}px` : 'max-content')) align-items: center; justify-content: center; } -.flex-column { - flex-direction: column; -} .order-1 { order: -1; } -.bold { - font-weight: bold; -} -.italic { - font-style: italic; -} .border { border: 2px solid v-bind(borderColor); } diff --git a/src/stories/components/Divider/Divider.vue b/src/stories/components/Divider/Divider.vue index 32f230a..54164cd 100644 --- a/src/stories/components/Divider/Divider.vue +++ b/src/stories/components/Divider/Divider.vue @@ -1,14 +1,9 @@ <script setup lang="ts"> import { computed } from 'vue'; -import type { TThemeColor } from '@interfaces/common'; import { convert500ThemeToColor } from '@helpers/colors'; +import type { IDividerProps } from '@interfaces/componentsProps'; -interface Props { - height?: number; - type?: 'solid' | 'dashed' | 'dotted'; - color?: TThemeColor; -} -const props = withDefaults(defineProps<Props>(), { +const props = withDefaults(defineProps<IDividerProps>(), { height: 1, type: 'solid', color: 'black', diff --git a/src/stories/components/Drawer/Drawer.vue b/src/stories/components/Drawer/Drawer.vue index bddd900..1587cbb 100644 --- a/src/stories/components/Drawer/Drawer.vue +++ b/src/stories/components/Drawer/Drawer.vue @@ -2,31 +2,19 @@ import { computed } from 'vue'; import { iconsSet } from '@/common/constants/icons'; import { convert500ThemeToColor, convert300ThemeToColor } from '@helpers/colors'; -import type { TIcons, TThemeColor } from '@interfaces/common'; +import type { IDrawerProps } from '@interfaces/componentsProps'; -const props = withDefaults( - defineProps<{ - position: 'left' | 'right' | 'top' | 'bottom'; - width?: string | number; - theme?: TThemeColor; - modal?: boolean; - dismissible?: boolean; - closeIcon?: TIcons; - headerDivider?: boolean; - footerDivider?: boolean; - }>(), - { - visible: false, - position: 'left', - width: 400, - modal: true, - dismissible: true, - theme: 'white', - closeIcon: 'CrossIcon', - headerDivider: false, - footerDivider: false, - }, -); +const props = withDefaults(defineProps<IDrawerProps>(), { + visible: false, + position: 'left', + width: 400, + modal: true, + dismissible: true, + theme: 'white', + closeIcon: 'CrossIcon', + headerDivider: false, + footerDivider: false, +}); const emit = defineEmits(['onClose']); const visible = defineModel<boolean>('visible'); diff --git a/src/stories/components/MenuDial/MenuDial.vue b/src/stories/components/MenuDial/MenuDial.vue index 381c4fa..01db4db 100644 --- a/src/stories/components/MenuDial/MenuDial.vue +++ b/src/stories/components/MenuDial/MenuDial.vue @@ -3,18 +3,19 @@ import { useVModel } from '@vueuse/core'; import PlusIcon from '@/shared/icons/PlusIcon.vue'; import { computed } from 'vue'; import { convertThemeToColorWhiteDefault } from './helpers/index'; +import type { TPosition, TSize, TTextStyle } from '@interfaces/common'; interface Props { isActive: boolean; items: { label: string; theme?: string; - textStyle?: 'bold' | 'italic'; + textStyle?: TTextStyle; onClick?: () => void; }[]; - size?: 'small' | 'medium' | 'large' | 'extraLarge'; + size?: TSize; theme?: string; - direction?: 'left' | 'right' | 'up' | 'down'; + direction?: TPosition; } const props = defineProps<Props>(); const emit = defineEmits(['update:isActive']); @@ -82,8 +83,8 @@ watch(isActive, () => { 'menuList', { menuListColumn: direction === 'up' || direction === 'down', - menuListOpened: isActive - } + menuListOpened: isActive, + }, ]" :style="menuListStyles" > @@ -102,8 +103,8 @@ watch(isActive, () => { '', { bold: item.textStyle === 'bold', - italic: item.textStyle === 'italic' - } + italic: item.textStyle === 'italic', + }, ]" > {{ item.label }} @@ -162,10 +163,4 @@ watch(isActive, () => { .menuElement:hover { filter: brightness(75%); } -.bold { - font-weight: bold; -} -.italic { - font-style: italic; -} </style> diff --git a/src/stories/components/Modal/Modal.vue b/src/stories/components/Modal/Modal.vue index b9142aa..c24538a 100644 --- a/src/stories/components/Modal/Modal.vue +++ b/src/stories/components/Modal/Modal.vue @@ -39,8 +39,8 @@ if (!props.onClose) { :class="[ 'modalBackground', { - openedModalBackground: isVisible - } + openedModalBackground: isVisible, + }, ]" ></section> <section @@ -48,8 +48,8 @@ if (!props.onClose) { :class="[ 'modal', { - openedModal: isVisible - } + openedModal: isVisible, + }, ]" > <header class="modalHeader"> diff --git a/src/stories/components/SelectButton/SelectButton.stories.ts b/src/stories/components/SelectButton/SelectButton.stories.ts index 9b19e46..9157794 100644 --- a/src/stories/components/SelectButton/SelectButton.stories.ts +++ b/src/stories/components/SelectButton/SelectButton.stories.ts @@ -20,7 +20,7 @@ const meta: Meta = { }, size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] }, rounded: { control: 'boolean' }, - activeBgColor: { + activeBackgroundColor: { control: 'select', options: [ 'white', @@ -110,7 +110,7 @@ export const LargeFull: Story = { ], border: 'sky', - activeBgColor: 'red', + activeBackgroundColor: 'red', rounded: true, disabled: false, size: 'large', diff --git a/src/stories/components/SelectButton/SelectButton.vue b/src/stories/components/SelectButton/SelectButton.vue index 4a99fb8..2f3761b 100644 --- a/src/stories/components/SelectButton/SelectButton.vue +++ b/src/stories/components/SelectButton/SelectButton.vue @@ -1,37 +1,18 @@ <script setup lang="ts"> import { computed } from 'vue'; -import type { TThemeColor } from '@interfaces/common'; import { convert500ThemeToColor } from '@helpers/colors'; +import type { ISBProps } from '@interfaces/componentsProps'; -const props = withDefaults( - defineProps<{ - options: { - label: string; - value?: never; - color?: TThemeColor; - activeColor?: TThemeColor; - backgroundColor?: TThemeColor; - isLabelHidden?: boolean; - iconPosition?: 'left' | 'right' | 'top' | 'bottom'; - textStyle?: 'bold' | 'italic'; - }[]; - size?: 'small' | 'medium' | 'large' | 'huge'; - rounded?: boolean; - activeBgColor?: TThemeColor; - border?: TThemeColor; - disabled?: boolean; - }>(), - { - size: 'medium', - border: 'black', - activeBgColor: 'sky', - }, -); +const props = withDefaults(defineProps<ISBProps>(), { + size: 'medium', + border: 'black', + activeBackgroundColor: 'sky', +}); const emit = defineEmits(['onClick']); -const value = defineModel<boolean>('value'); +const value = defineModel<never>('value'); -const activeBgColor = computed(() => - props.activeBgColor ? convert500ThemeToColor(props.activeBgColor) : '', +const activeBackgroundColorComputed = computed(() => + props.activeBackgroundColor ? convert500ThemeToColor(props.activeBackgroundColor) : '', ); const borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : '')); const textSize = computed(() => { @@ -92,13 +73,13 @@ const buttonHeight = computed(() => { :style="`padding: ${buttonPadding}`" @click.prevent=" () => { - value = item?.value ?? item.label; + value = (item.value as never) ?? item.label; emit('onClick', value); } " > <span - :style="`background-color: ${activeBgColor && (value === item.value || value === item.label) ? activeBgColor : convert500ThemeToColor(item.backgroundColor ?? 'white')}`" + :style="`background-color: ${activeBackgroundColorComputed && ((value && value === item.value) || value === item.label) ? activeBackgroundColorComputed : convert500ThemeToColor(item.backgroundColor ?? 'white')}`" :class="[ 'background', { @@ -169,18 +150,9 @@ const buttonHeight = computed(() => { align-items: center; justify-content: center; } -.flex-column { - flex-direction: column; -} .order-1 { order: -1; } -.bold { - font-weight: bold; -} -.italic { - font-style: italic; -} .border { border: 2px solid v-bind(borderColor); } diff --git a/src/stories/components/ToggleSwitch/ToggleSwitch.vue b/src/stories/components/ToggleSwitch/ToggleSwitch.vue index c91b9bc..c61184a 100644 --- a/src/stories/components/ToggleSwitch/ToggleSwitch.vue +++ b/src/stories/components/ToggleSwitch/ToggleSwitch.vue @@ -1,23 +1,14 @@ <script setup lang="ts"> import { computed } from 'vue'; -import type { TThemeColor, TThemeColorNoWhite } from '@interfaces/common'; import { convert500ThemeToColor, convert800ThemeToColor } from '@helpers/colors'; +import type { ITSProps } from '@interfaces/componentsProps'; -const props = withDefaults( - defineProps<{ - size?: 'small' | 'medium' | 'large' | 'huge'; - theme?: TThemeColorNoWhite; - negativeTheme?: TThemeColor; - darkNegative?: boolean; - disabled?: boolean; - }>(), - { - size: 'medium', - theme: 'sky', - negativeTheme: 'black', - darkNegative: true, - }, -); +const props = withDefaults(defineProps<ITSProps>(), { + size: 'medium', + theme: 'sky', + negativeTheme: 'black', + darkNegative: true, +}); const active = defineModel<boolean>('active'); const themeColor = computed(() => convert500ThemeToColor(props.theme)); diff --git a/src/stories/components/TreeList/TreeItems.vue b/src/stories/components/TreeList/TreeItems.vue index 68ebbe7..46d7ef0 100644 --- a/src/stories/components/TreeList/TreeItems.vue +++ b/src/stories/components/TreeList/TreeItems.vue @@ -1,18 +1,10 @@ <script setup lang="ts"> import { iconsSet } from '@/common/constants/icons'; import TriangleIcon from '@stories/icons/Mono/TriangleIcon.vue'; -import type { ITreeItem } from '@interfaces/components'; -import type { TThemeColor } from '@interfaces/common'; import { convert500ThemeToColor } from '@helpers/colors'; +import type { ITIProps } from '@interfaces/componentsProps'; -defineProps<{ - state: { - isOpen: boolean; - label: string; - }[]; - items: ITreeItem[]; - textColor: TThemeColor; -}>(); +defineProps<ITIProps>(); const emit = defineEmits(['toggleIsOpen', 'onClick']); </script> @@ -71,10 +63,16 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); { bold: item.textStyle === 'bold', italic: item.textStyle === 'italic', + isDarkerOnHover: item.link, }, ]" :style="`color: ${item.color ? convert500ThemeToColor(item.color) : textColor}`" - @click="emit('onClick', item.link)" + @click=" + () => { + item.isLinkClicked = true; + emit('onClick', item.link); + } + " >{{ item.label }}</a > <component @@ -87,9 +85,10 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); </section> <section class="children"> <TreeItems - :items="item.children" + :items="item.children ?? []" :state="state" :textColor="textColor" + :themeColor="themeColor" @toggleIsOpen="emit('toggleIsOpen', $event)" /> </section> @@ -145,10 +144,7 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); .pl27 { padding-left: 27px; } -.bold { - font-weight: bold; -} -.italic { - font-style: italic; +.isDarkerOnHover:hover { + filter: brightness(80%); } </style> diff --git a/src/stories/components/TreeList/TreeList.stories.ts b/src/stories/components/TreeList/TreeList.stories.ts index 5ccd861..51b0fda 100644 --- a/src/stories/components/TreeList/TreeList.stories.ts +++ b/src/stories/components/TreeList/TreeList.stories.ts @@ -15,7 +15,7 @@ const meta: Meta = { }, }, argTypes: { - items: { control: 'array' }, + items: { control: 'object' }, maxWidth: { control: 'number' }, expand: { control: 'boolean' }, theme: { diff --git a/src/stories/components/TreeList/TreeList.vue b/src/stories/components/TreeList/TreeList.vue index d13489d..061fe64 100644 --- a/src/stories/components/TreeList/TreeList.vue +++ b/src/stories/components/TreeList/TreeList.vue @@ -1,32 +1,29 @@ <script setup lang="ts"> import { computed, ref, watch } from 'vue'; -import type { ITreeItem } from '@interfaces/components'; -import type { TThemeColor } from '@interfaces/common'; +import type { ITreeItem } from '@interfaces/componentsProp'; import { convert500ThemeToColor } from '@helpers/colors'; import TreeItems from '@stories/components/TreeList/TreeItems.vue'; +import type { ITLProps } from '@interfaces/componentsProps'; -const props = withDefaults( - defineProps<{ - items?: ITreeItem[]; - maxWidth?: number; - expand?: boolean; - theme?: TThemeColor; - }>(), - { - theme: 'white', - maxWidth: 300, - }, -); +interface IStateItem { + isOpen: boolean; + label: string; +} + +const props = withDefaults(defineProps<ITLProps>(), { + theme: 'white', + maxWidth: 300, +}); const emit = defineEmits(['onClick']); const items = computed(() => props.items); const themeColor = computed(() => convert500ThemeToColor(props.theme)); const textColor = computed(() => { - if (!props.theme) return '#000000'; - if (props.theme === 'white') return '#000000'; - return '#ffffff'; + if (!props.theme) return 'black'; + if (props.theme === 'white') return 'black'; + return 'white'; }); -const state = ref([]); +const state = ref<IStateItem[]>([]); const setItemChildrenToState = (items: ITreeItem[]) => { for (const item of items) { state.value.push({ @@ -51,10 +48,15 @@ watch( immediate: true, }, ); -const toggleIsOpen = (item) => +const toggleIsOpen = (item: ITreeItem) => { + if (item.isLinkClicked) { + item.isLinkClicked = false; + return; + } state.value.map((itemState) => { if (itemState.label === item.label) itemState.isOpen = !itemState.isOpen; }); +}; </script> <template> @@ -66,6 +68,7 @@ const toggleIsOpen = (item) => :items="items" :state="state" :textColor="textColor" + :themeColor="themeColor" @toggleIsOpen="toggleIsOpen" @onClick="emit('onClick')" /> diff --git a/src/stories/components/examples/ExampleStorybookButton/ButtonStorybook.vue b/src/stories/components/examples/ExampleStorybookButton/ButtonStorybook.vue index eac1424..0a7be63 100644 --- a/src/stories/components/examples/ExampleStorybookButton/ButtonStorybook.vue +++ b/src/stories/components/examples/ExampleStorybookButton/ButtonStorybook.vue @@ -1,30 +1,32 @@ <template> - <button type="button" :class="classes" @click="onClick" :style="style">{{ label }} </button> + <button type="button" :class="classes" @click="onClick" :style="style">{{ label }}</button> </template> <script lang="ts" setup> import './buttonStorybook.css'; import { computed } from 'vue'; -const props = withDefaults(defineProps<{ - /** - * The label of the button - */ - label: string, - /** - * primary or secondary button - */ - primary?: boolean, - /** - * size of the button - */ - size?: 'small' | 'medium' | 'large', - /** - * background color of the button - */ - backgroundColor?: string, - -}>(), { primary: false }); +const props = withDefaults( + defineProps<{ + /** + * The label of the button + */ + label: string; + /** + * primary or secondary button + */ + primary?: boolean; + /** + * size of the button + */ + size?: 'small' | 'medium' | 'large'; + /** + * background color of the button + */ + backgroundColor?: string; + }>(), + { primary: false }, +); const emit = defineEmits<{ (e: 'click', id: number): void; @@ -38,11 +40,10 @@ const classes = computed(() => ({ })); const style = computed(() => ({ - backgroundColor: props.backgroundColor + backgroundColor: props.backgroundColor, })); const onClick = () => { - emit("click", 1) + emit('click', 1); }; - </script> -- GitLab