Skip to content
Snippets Groups Projects
Commit 4d9daf86 authored by Дмитрий Малюгин's avatar Дмитрий Малюгин :clock4:
Browse files

refactor: props of components

parent ab84b5f5
No related branches found
No related tags found
1 merge request!1Project setup and add 9 initial components
Showing
with 470 additions and 391 deletions
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
.flex-column {
flex-direction: column;
}
@import './components.css';
:root { :root {
--gray-100: #f3f4f6; --gray-100: #f3f4f6;
--gray-200: #e5e7eb; --gray-200: #e5e7eb;
--gray-300: #d1d5db; --gray-300: #d1d5db;
--gray-400: #9ca3af; --gray-400: #9ca3af;
--gray-500: #6b7280; --gray-500: #6b7280;
--gray-600: #4b5563; --gray-600: #4b5563;
--gray-700: #374151; --gray-700: #374151;
--gray-800: #1f2937; --gray-800: #1f2937;
--gray-900: #111827; --gray-900: #111827;
--slate-100: #f1f5f9; --slate-100: #f1f5f9;
--slate-200: #e2e8f0; --slate-200: #e2e8f0;
--slate-300: #cbd5e1; --slate-300: #cbd5e1;
--slate-400: #94a3b8; --slate-400: #94a3b8;
--slate-500: #64748b; --slate-500: #64748b;
--slate-600: #475569; --slate-600: #475569;
--slate-700: #334155; --slate-700: #334155;
--slate-800: #1e293b; --slate-800: #1e293b;
--slate-900: #0f172a; --slate-900: #0f172a;
--red-100: #fee2e2; --red-100: #fee2e2;
--red-200: #fecaca; --red-200: #fecaca;
--red-300: #fca5a5; --red-300: #fca5a5;
--red-400: #f87171; --red-400: #f87171;
--red-500: #ef4444; --red-500: #ef4444;
--red-600: #dc2626; --red-600: #dc2626;
--red-700: #b91c1c; --red-700: #b91c1c;
--red-800: #991b1b; --red-800: #991b1b;
--red-900: #7f1d1d; --red-900: #7f1d1d;
--orange-100: #ffedd5; --orange-100: #ffedd5;
--orange-200: #fed7aa; --orange-200: #fed7aa;
--orange-300: #fdba74; --orange-300: #fdba74;
--orange-400: #fb923c; --orange-400: #fb923c;
--orange-500: #f97316; --orange-500: #f97316;
--orange-600: #ea580c; --orange-600: #ea580c;
--orange-700: #c2410c; --orange-700: #c2410c;
--orange-800: #9a3412; --orange-800: #9a3412;
--orange-900: #7c2d12; --orange-900: #7c2d12;
--amber-100: #fef3c7; --amber-100: #fef3c7;
--amber-200: #fde68a; --amber-200: #fde68a;
--amber-300: #fcd34d; --amber-300: #fcd34d;
--amber-400: #fbbf24; --amber-400: #fbbf24;
--amber-500: #f59e0b; --amber-500: #f59e0b;
--amber-600: #d97706; --amber-600: #d97706;
--amber-700: #b45309; --amber-700: #b45309;
--amber-800: #92400e; --amber-800: #92400e;
--amber-900: #78350f; --amber-900: #78350f;
--yellow-100: #fef9c3; --yellow-100: #fef9c3;
--yellow-200: #fef08a; --yellow-200: #fef08a;
--yellow-300: #fde047; --yellow-300: #fde047;
--yellow-400: #facc15; --yellow-400: #facc15;
--yellow-500: #eab308; --yellow-500: #eab308;
--yellow-600: #ca8a04; --yellow-600: #ca8a04;
--yellow-700: #a16207; --yellow-700: #a16207;
--yellow-800: #854d0e; --yellow-800: #854d0e;
--yellow-900: #713f12; --yellow-900: #713f12;
--lime-100: #ecfccb; --lime-100: #ecfccb;
--lime-200: #d9f99d; --lime-200: #d9f99d;
--lime-300: #bef264; --lime-300: #bef264;
--lime-400: #a3e635; --lime-400: #a3e635;
--lime-500: #84cc16; --lime-500: #84cc16;
--lime-600: #65a30d; --lime-600: #65a30d;
--lime-700: #4d7c0f; --lime-700: #4d7c0f;
--lime-800: #3f6212; --lime-800: #3f6212;
--lime-900: #365314; --lime-900: #365314;
--green-100: #dcfce7; --green-100: #dcfce7;
--green-200: #bbf7d0; --green-200: #bbf7d0;
--green-300: #86efac; --green-300: #86efac;
--green-400: #4ade80; --green-400: #4ade80;
--green-500: #22c55e; --green-500: #22c55e;
--green-600: #16a34a; --green-600: #16a34a;
--green-700: #15803d; --green-700: #15803d;
--green-800: #166534; --green-800: #166534;
--green-900: #14532d; --green-900: #14532d;
--teal-100: #ccfbf1; --teal-100: #ccfbf1;
--teal-200: #99f6e4; --teal-200: #99f6e4;
--teal-300: #5eead4; --teal-300: #5eead4;
--teal-400: #2dd4bf; --teal-400: #2dd4bf;
--teal-500: #14b8a6; --teal-500: #14b8a6;
--teal-600: #0d9488; --teal-600: #0d9488;
--teal-700: #0f766e; --teal-700: #0f766e;
--teal-800: #115e59; --teal-800: #115e59;
--teal-900: #134e4a; --teal-900: #134e4a;
--sky-100: #e0f2fe; --sky-100: #e0f2fe;
--sky-200: #bae6fd; --sky-200: #bae6fd;
--sky-300: #7dd3fc; --sky-300: #7dd3fc;
--sky-400: #38bdf8; --sky-400: #38bdf8;
--sky-500: #0ea5e9; --sky-500: #0ea5e9;
--sky-600: #0284c7; --sky-600: #0284c7;
--sky-700: #0369a1; --sky-700: #0369a1;
--sky-800: #075985; --sky-800: #075985;
--sky-900: #0c4a6e; --sky-900: #0c4a6e;
--blue-100: #dbeafe; --blue-100: #dbeafe;
--blue-200: #bfdbfe; --blue-200: #bfdbfe;
--blue-300: #93c5fd; --blue-300: #93c5fd;
--blue-400: #60a5fa; --blue-400: #60a5fa;
--blue-500: #3b82f6; --blue-500: #3b82f6;
--blue-600: #2563eb; --blue-600: #2563eb;
--blue-700: #1d4ed8; --blue-700: #1d4ed8;
--blue-800: #1e40af; --blue-800: #1e40af;
--blue-900: #1e3a8a; --blue-900: #1e3a8a;
--indigo-100: #e0e7ff; --indigo-100: #e0e7ff;
--indigo-200: #c7d2fe; --indigo-200: #c7d2fe;
--indigo-300: #a5b4fc; --indigo-300: #a5b4fc;
--indigo-400: #818cf8; --indigo-400: #818cf8;
--indigo-500: #6366f1; --indigo-500: #6366f1;
--indigo-600: #4f46e5; --indigo-600: #4f46e5;
--indigo-700: #4338ca; --indigo-700: #4338ca;
--indigo-800: #3730a3; --indigo-800: #3730a3;
--indigo-900: #312e81; --indigo-900: #312e81;
--purple-100: #f3e8ff; --purple-100: #f3e8ff;
--purple-200: #e9d5ff; --purple-200: #e9d5ff;
--purple-300: #d8b4fe; --purple-300: #d8b4fe;
--purple-400: #c084fc; --purple-400: #c084fc;
--purple-500: #a855f7; --purple-500: #a855f7;
--purple-600: #9333ea; --purple-600: #9333ea;
--purple-700: #7e22ce; --purple-700: #7e22ce;
--purple-800: #6b21a8; --purple-800: #6b21a8;
--purple-900: #581c87; --purple-900: #581c87;
--fuchsia-100: #fae8ff; --fuchsia-100: #fae8ff;
--fuchsia-200: #f5d0fe; --fuchsia-200: #f5d0fe;
--fuchsia-300: #f0abfc; --fuchsia-300: #f0abfc;
--fuchsia-400: #e879f9; --fuchsia-400: #e879f9;
--fuchsia-500: #d946ef; --fuchsia-500: #d946ef;
--fuchsia-600: #c026d3; --fuchsia-600: #c026d3;
--fuchsia-700: #a21caf; --fuchsia-700: #a21caf;
--fuchsia-800: #86198f; --fuchsia-800: #86198f;
--fuchsia-900: #701a75; --fuchsia-900: #701a75;
--pink-100: #fce7f3; --pink-100: #fce7f3;
--pink-200: #fbcfe8; --pink-200: #fbcfe8;
--pink-300: #f9a8d4; --pink-300: #f9a8d4;
--pink-400: #f472b6; --pink-400: #f472b6;
--pink-500: #ec4899; --pink-500: #ec4899;
--pink-600: #db2777; --pink-600: #db2777;
--pink-700: #be185d; --pink-700: #be185d;
--pink-800: #9d174d; --pink-800: #9d174d;
--pink-900: #831843; --pink-900: #831843;
--rose-100: #ffe4e6; --rose-100: #ffe4e6;
--rose-200: #fecdd3; --rose-200: #fecdd3;
--rose-300: #fda4af; --rose-300: #fda4af;
--rose-400: #fb7185; --rose-400: #fb7185;
--rose-500: #f43f5e; --rose-500: #f43f5e;
--rose-600: #e11d48; --rose-600: #e11d48;
--rose-700: #be123c; --rose-700: #be123c;
--rose-800: #9f1239; --rose-800: #9f1239;
--rose-900: #881337; --rose-900: #881337;
} }
body { body {
min-height: 100vh; min-height: 100vh;
overflow-x: hidden; overflow-x: hidden;
} }
* { * {
font-family: Arial, serif; font-family: Arial, serif;
} }
#app { #app {
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-flow: column; flex-flow: column;
} }
#sheetContainer { #sheetContainer {
padding-top: 80px; padding-top: 80px;
} }
#app > main { #app > main {
flex: 1 1 auto; flex: 1 1 auto;
} }
/* Reset and base styles */ /* Reset and base styles */
* { * {
padding: 0; padding: 0;
margin: 0; margin: 0;
border: none; border: none;
box-sizing: border-box; box-sizing: border-box;
} }
*, *,
*::before, *::before,
*::after { *::after {
box-sizing: border-box; box-sizing: border-box;
font-weight: 500; font-weight: 500;
} }
/* Links */ /* Links */
a, a:link, a:visited { a,
text-decoration: none; a:link,
a:visited {
text-decoration: none;
} }
a:hover { a:hover {
text-decoration: none; text-decoration: none;
} }
/* Common */ /* Common */
aside, nav, footer, header, section, main { aside,
display: block; nav,
footer,
header,
section,
main {
display: block;
} }
h1, h2, h3, h4, h5, h6, p { h1,
font-size: inherit; h2,
font-weight: inherit; h3,
h4,
h5,
h6,
p {
font-size: inherit;
font-weight: inherit;
} }
ul, ul li { ul,
list-style: none; ul li {
list-style: none;
} }
img { img {
vertical-align: top; vertical-align: top;
} }
img, svg { img,
max-width: 100%; svg {
height: auto; max-width: 100%;
height: auto;
} }
address { address {
font-style: normal; font-style: normal;
} }
/* Form */ /* Form */
input, textarea, button, select { input,
font-family: inherit; textarea,
font-size: inherit; button,
color: inherit; select {
background-color: transparent; font-family: inherit;
font-size: inherit;
color: inherit;
background-color: transparent;
} }
input::-ms-clear { input::-ms-clear {
display: none; display: none;
} }
button, input[type="submit"] { button,
display: inline-block; input[type='submit'] {
box-shadow: none; display: inline-block;
background-color: transparent; box-shadow: none;
background: none; background-color: transparent;
cursor: pointer; background: none;
cursor: pointer;
} }
input:focus, input:active, input:focus,
button:focus, button:active { input:active,
outline: none; button:focus,
button:active {
outline: none;
} }
button::-moz-focus-inner { button::-moz-focus-inner {
padding: 0; padding: 0;
border: 0; border: 0;
} }
label { label {
cursor: pointer; cursor: pointer;
} }
legend { legend {
display: block; display: block;
} }
input[type=file], /* FF, IE7+, chrome (except button) */ input[type=file], /* FF, IE7+, chrome (except button) */
input[type=file]::-webkit-file-upload-button { input[type=file]::-webkit-file-upload-button {
cursor: pointer; cursor: pointer;
} }
\ No newline at end of file
...@@ -74,6 +74,7 @@ export const convert500ThemeToColor = (theme: string | undefined) => { ...@@ -74,6 +74,7 @@ export const convert500ThemeToColor = (theme: string | undefined) => {
case 'black': case 'black':
return '#000000'; return '#000000';
} }
return '#000000';
}; };
export const convert800ThemeToColor = (theme: string | undefined) => { export const convert800ThemeToColor = (theme: string | undefined) => {
......
...@@ -19,4 +19,12 @@ export type TThemeColor = ...@@ -19,4 +19,12 @@ export type TThemeColor =
export type TThemeColorNoWhite = Exclude<TThemeColor, 'white'>; 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; export type TIcons = keyof typeof iconsSet;
import type { TIcons, TThemeColor } from '@interfaces/common'; import type { TIcons, TPosition, TTextStyle, TThemeColor } from '@interfaces/common';
export interface ITreeItem { export interface ITreeItem {
label: string; label: string;
link?: string; link?: string;
linkBlank?: boolean; linkBlank?: boolean;
color?: TThemeColor; color?: TThemeColor;
textStyle?: 'bold' | 'italic'; textStyle?: TTextStyle;
isTriangleToColor?: boolean; isTriangleToColor?: boolean;
iconBefore?: TIcons; iconBefore?: TIcons;
iconAfter?: TIcons; iconAfter?: TIcons;
iconColor?: TThemeColor; iconColor?: TThemeColor;
children?: ITreeItem[]; 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;
} }
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;
}
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue'; import { computed } from 'vue';
import type { TThemeColor } from '@interfaces/common';
import { convert500ThemeToColor } from '@helpers/colors'; 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 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 borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : ''));
const textSize = computed(() => { const textSize = computed(() => {
switch (props.size) { switch (props.size) {
...@@ -64,7 +52,7 @@ const width = computed(() => (props.width ? `${props.width}px` : 'max-content')) ...@@ -64,7 +52,7 @@ const width = computed(() => (props.width ? `${props.width}px` : 'max-content'))
<span :style="`background-color: ${themeColor}`" class="background"></span> <span :style="`background-color: ${themeColor}`" class="background"></span>
<span <span
v-if="label || !iconOnly" v-if="label || !iconOnly"
:style="`color: ${textColor}; font-size: ${textSize}`" :style="`color: ${textColorComputed}; font-size: ${textSize}`"
:class="[ :class="[
'text', 'text',
{ {
...@@ -125,18 +113,9 @@ const width = computed(() => (props.width ? `${props.width}px` : 'max-content')) ...@@ -125,18 +113,9 @@ const width = computed(() => (props.width ? `${props.width}px` : 'max-content'))
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.flex-column {
flex-direction: column;
}
.order-1 { .order-1 {
order: -1; order: -1;
} }
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
.border { .border {
border: 2px solid v-bind(borderColor); border: 2px solid v-bind(borderColor);
} }
......
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue'; import { computed } from 'vue';
import type { TThemeColor } from '@interfaces/common';
import { convert500ThemeToColor } from '@helpers/colors'; import { convert500ThemeToColor } from '@helpers/colors';
import type { IDividerProps } from '@interfaces/componentsProps';
interface Props { const props = withDefaults(defineProps<IDividerProps>(), {
height?: number;
type?: 'solid' | 'dashed' | 'dotted';
color?: TThemeColor;
}
const props = withDefaults(defineProps<Props>(), {
height: 1, height: 1,
type: 'solid', type: 'solid',
color: 'black', color: 'black',
......
...@@ -2,31 +2,19 @@ ...@@ -2,31 +2,19 @@
import { computed } from 'vue'; import { computed } from 'vue';
import { iconsSet } from '@/common/constants/icons'; import { iconsSet } from '@/common/constants/icons';
import { convert500ThemeToColor, convert300ThemeToColor } from '@helpers/colors'; import { convert500ThemeToColor, convert300ThemeToColor } from '@helpers/colors';
import type { TIcons, TThemeColor } from '@interfaces/common'; import type { IDrawerProps } from '@interfaces/componentsProps';
const props = withDefaults( const props = withDefaults(defineProps<IDrawerProps>(), {
defineProps<{ visible: false,
position: 'left' | 'right' | 'top' | 'bottom'; position: 'left',
width?: string | number; width: 400,
theme?: TThemeColor; modal: true,
modal?: boolean; dismissible: true,
dismissible?: boolean; theme: 'white',
closeIcon?: TIcons; closeIcon: 'CrossIcon',
headerDivider?: boolean; headerDivider: false,
footerDivider?: boolean; footerDivider: false,
}>(), });
{
visible: false,
position: 'left',
width: 400,
modal: true,
dismissible: true,
theme: 'white',
closeIcon: 'CrossIcon',
headerDivider: false,
footerDivider: false,
},
);
const emit = defineEmits(['onClose']); const emit = defineEmits(['onClose']);
const visible = defineModel<boolean>('visible'); const visible = defineModel<boolean>('visible');
......
...@@ -3,18 +3,19 @@ import { useVModel } from '@vueuse/core'; ...@@ -3,18 +3,19 @@ import { useVModel } from '@vueuse/core';
import PlusIcon from '@/shared/icons/PlusIcon.vue'; import PlusIcon from '@/shared/icons/PlusIcon.vue';
import { computed } from 'vue'; import { computed } from 'vue';
import { convertThemeToColorWhiteDefault } from './helpers/index'; import { convertThemeToColorWhiteDefault } from './helpers/index';
import type { TPosition, TSize, TTextStyle } from '@interfaces/common';
interface Props { interface Props {
isActive: boolean; isActive: boolean;
items: { items: {
label: string; label: string;
theme?: string; theme?: string;
textStyle?: 'bold' | 'italic'; textStyle?: TTextStyle;
onClick?: () => void; onClick?: () => void;
}[]; }[];
size?: 'small' | 'medium' | 'large' | 'extraLarge'; size?: TSize;
theme?: string; theme?: string;
direction?: 'left' | 'right' | 'up' | 'down'; direction?: TPosition;
} }
const props = defineProps<Props>(); const props = defineProps<Props>();
const emit = defineEmits(['update:isActive']); const emit = defineEmits(['update:isActive']);
...@@ -82,8 +83,8 @@ watch(isActive, () => { ...@@ -82,8 +83,8 @@ watch(isActive, () => {
'menuList', 'menuList',
{ {
menuListColumn: direction === 'up' || direction === 'down', menuListColumn: direction === 'up' || direction === 'down',
menuListOpened: isActive menuListOpened: isActive,
} },
]" ]"
:style="menuListStyles" :style="menuListStyles"
> >
...@@ -102,8 +103,8 @@ watch(isActive, () => { ...@@ -102,8 +103,8 @@ watch(isActive, () => {
'', '',
{ {
bold: item.textStyle === 'bold', bold: item.textStyle === 'bold',
italic: item.textStyle === 'italic' italic: item.textStyle === 'italic',
} },
]" ]"
> >
{{ item.label }} {{ item.label }}
...@@ -162,10 +163,4 @@ watch(isActive, () => { ...@@ -162,10 +163,4 @@ watch(isActive, () => {
.menuElement:hover { .menuElement:hover {
filter: brightness(75%); filter: brightness(75%);
} }
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
</style> </style>
...@@ -39,8 +39,8 @@ if (!props.onClose) { ...@@ -39,8 +39,8 @@ if (!props.onClose) {
:class="[ :class="[
'modalBackground', 'modalBackground',
{ {
openedModalBackground: isVisible openedModalBackground: isVisible,
} },
]" ]"
></section> ></section>
<section <section
...@@ -48,8 +48,8 @@ if (!props.onClose) { ...@@ -48,8 +48,8 @@ if (!props.onClose) {
:class="[ :class="[
'modal', 'modal',
{ {
openedModal: isVisible openedModal: isVisible,
} },
]" ]"
> >
<header class="modalHeader"> <header class="modalHeader">
......
...@@ -20,7 +20,7 @@ const meta: Meta = { ...@@ -20,7 +20,7 @@ const meta: Meta = {
}, },
size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] }, size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] },
rounded: { control: 'boolean' }, rounded: { control: 'boolean' },
activeBgColor: { activeBackgroundColor: {
control: 'select', control: 'select',
options: [ options: [
'white', 'white',
...@@ -110,7 +110,7 @@ export const LargeFull: Story = { ...@@ -110,7 +110,7 @@ export const LargeFull: Story = {
], ],
border: 'sky', border: 'sky',
activeBgColor: 'red', activeBackgroundColor: 'red',
rounded: true, rounded: true,
disabled: false, disabled: false,
size: 'large', size: 'large',
......
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue'; import { computed } from 'vue';
import type { TThemeColor } from '@interfaces/common';
import { convert500ThemeToColor } from '@helpers/colors'; import { convert500ThemeToColor } from '@helpers/colors';
import type { ISBProps } from '@interfaces/componentsProps';
const props = withDefaults( const props = withDefaults(defineProps<ISBProps>(), {
defineProps<{ size: 'medium',
options: { border: 'black',
label: string; activeBackgroundColor: 'sky',
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 emit = defineEmits(['onClick']); const emit = defineEmits(['onClick']);
const value = defineModel<boolean>('value'); const value = defineModel<never>('value');
const activeBgColor = computed(() => const activeBackgroundColorComputed = computed(() =>
props.activeBgColor ? convert500ThemeToColor(props.activeBgColor) : '', props.activeBackgroundColor ? convert500ThemeToColor(props.activeBackgroundColor) : '',
); );
const borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : '')); const borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : ''));
const textSize = computed(() => { const textSize = computed(() => {
...@@ -92,13 +73,13 @@ const buttonHeight = computed(() => { ...@@ -92,13 +73,13 @@ const buttonHeight = computed(() => {
:style="`padding: ${buttonPadding}`" :style="`padding: ${buttonPadding}`"
@click.prevent=" @click.prevent="
() => { () => {
value = item?.value ?? item.label; value = (item.value as never) ?? item.label;
emit('onClick', value); emit('onClick', value);
} }
" "
> >
<span <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="[ :class="[
'background', 'background',
{ {
...@@ -169,18 +150,9 @@ const buttonHeight = computed(() => { ...@@ -169,18 +150,9 @@ const buttonHeight = computed(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.flex-column {
flex-direction: column;
}
.order-1 { .order-1 {
order: -1; order: -1;
} }
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
.border { .border {
border: 2px solid v-bind(borderColor); border: 2px solid v-bind(borderColor);
} }
......
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue'; import { computed } from 'vue';
import type { TThemeColor, TThemeColorNoWhite } from '@interfaces/common';
import { convert500ThemeToColor, convert800ThemeToColor } from '@helpers/colors'; import { convert500ThemeToColor, convert800ThemeToColor } from '@helpers/colors';
import type { ITSProps } from '@interfaces/componentsProps';
const props = withDefaults( const props = withDefaults(defineProps<ITSProps>(), {
defineProps<{ size: 'medium',
size?: 'small' | 'medium' | 'large' | 'huge'; theme: 'sky',
theme?: TThemeColorNoWhite; negativeTheme: 'black',
negativeTheme?: TThemeColor; darkNegative: true,
darkNegative?: boolean; });
disabled?: boolean;
}>(),
{
size: 'medium',
theme: 'sky',
negativeTheme: 'black',
darkNegative: true,
},
);
const active = defineModel<boolean>('active'); const active = defineModel<boolean>('active');
const themeColor = computed(() => convert500ThemeToColor(props.theme)); const themeColor = computed(() => convert500ThemeToColor(props.theme));
......
<script setup lang="ts"> <script setup lang="ts">
import { iconsSet } from '@/common/constants/icons'; import { iconsSet } from '@/common/constants/icons';
import TriangleIcon from '@stories/icons/Mono/TriangleIcon.vue'; 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 { convert500ThemeToColor } from '@helpers/colors';
import type { ITIProps } from '@interfaces/componentsProps';
defineProps<{ defineProps<ITIProps>();
state: {
isOpen: boolean;
label: string;
}[];
items: ITreeItem[];
textColor: TThemeColor;
}>();
const emit = defineEmits(['toggleIsOpen', 'onClick']); const emit = defineEmits(['toggleIsOpen', 'onClick']);
</script> </script>
...@@ -71,10 +63,16 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); ...@@ -71,10 +63,16 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']);
{ {
bold: item.textStyle === 'bold', bold: item.textStyle === 'bold',
italic: item.textStyle === 'italic', italic: item.textStyle === 'italic',
isDarkerOnHover: item.link,
}, },
]" ]"
:style="`color: ${item.color ? convert500ThemeToColor(item.color) : textColor}`" :style="`color: ${item.color ? convert500ThemeToColor(item.color) : textColor}`"
@click="emit('onClick', item.link)" @click="
() => {
item.isLinkClicked = true;
emit('onClick', item.link);
}
"
>{{ item.label }}</a >{{ item.label }}</a
> >
<component <component
...@@ -87,9 +85,10 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); ...@@ -87,9 +85,10 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']);
</section> </section>
<section class="children"> <section class="children">
<TreeItems <TreeItems
:items="item.children" :items="item.children ?? []"
:state="state" :state="state"
:textColor="textColor" :textColor="textColor"
:themeColor="themeColor"
@toggleIsOpen="emit('toggleIsOpen', $event)" @toggleIsOpen="emit('toggleIsOpen', $event)"
/> />
</section> </section>
...@@ -145,10 +144,7 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']); ...@@ -145,10 +144,7 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']);
.pl27 { .pl27 {
padding-left: 27px; padding-left: 27px;
} }
.bold { .isDarkerOnHover:hover {
font-weight: bold; filter: brightness(80%);
}
.italic {
font-style: italic;
} }
</style> </style>
...@@ -15,7 +15,7 @@ const meta: Meta = { ...@@ -15,7 +15,7 @@ const meta: Meta = {
}, },
}, },
argTypes: { argTypes: {
items: { control: 'array' }, items: { control: 'object' },
maxWidth: { control: 'number' }, maxWidth: { control: 'number' },
expand: { control: 'boolean' }, expand: { control: 'boolean' },
theme: { theme: {
......
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import type { ITreeItem } from '@interfaces/components'; import type { ITreeItem } from '@interfaces/componentsProp';
import type { TThemeColor } from '@interfaces/common';
import { convert500ThemeToColor } from '@helpers/colors'; import { convert500ThemeToColor } from '@helpers/colors';
import TreeItems from '@stories/components/TreeList/TreeItems.vue'; import TreeItems from '@stories/components/TreeList/TreeItems.vue';
import type { ITLProps } from '@interfaces/componentsProps';
const props = withDefaults( interface IStateItem {
defineProps<{ isOpen: boolean;
items?: ITreeItem[]; label: string;
maxWidth?: number; }
expand?: boolean;
theme?: TThemeColor; const props = withDefaults(defineProps<ITLProps>(), {
}>(), theme: 'white',
{ maxWidth: 300,
theme: 'white', });
maxWidth: 300,
},
);
const emit = defineEmits(['onClick']); const emit = defineEmits(['onClick']);
const items = computed(() => props.items); const items = computed(() => props.items);
const themeColor = computed(() => convert500ThemeToColor(props.theme)); const themeColor = computed(() => convert500ThemeToColor(props.theme));
const textColor = computed(() => { const textColor = computed(() => {
if (!props.theme) return '#000000'; if (!props.theme) return 'black';
if (props.theme === 'white') return '#000000'; if (props.theme === 'white') return 'black';
return '#ffffff'; return 'white';
}); });
const state = ref([]); const state = ref<IStateItem[]>([]);
const setItemChildrenToState = (items: ITreeItem[]) => { const setItemChildrenToState = (items: ITreeItem[]) => {
for (const item of items) { for (const item of items) {
state.value.push({ state.value.push({
...@@ -51,10 +48,15 @@ watch( ...@@ -51,10 +48,15 @@ watch(
immediate: true, immediate: true,
}, },
); );
const toggleIsOpen = (item) => const toggleIsOpen = (item: ITreeItem) => {
if (item.isLinkClicked) {
item.isLinkClicked = false;
return;
}
state.value.map((itemState) => { state.value.map((itemState) => {
if (itemState.label === item.label) itemState.isOpen = !itemState.isOpen; if (itemState.label === item.label) itemState.isOpen = !itemState.isOpen;
}); });
};
</script> </script>
<template> <template>
...@@ -66,6 +68,7 @@ const toggleIsOpen = (item) => ...@@ -66,6 +68,7 @@ const toggleIsOpen = (item) =>
:items="items" :items="items"
:state="state" :state="state"
:textColor="textColor" :textColor="textColor"
:themeColor="themeColor"
@toggleIsOpen="toggleIsOpen" @toggleIsOpen="toggleIsOpen"
@onClick="emit('onClick')" @onClick="emit('onClick')"
/> />
......
<template> <template>
<button type="button" :class="classes" @click="onClick" :style="style">{{ label }} </button> <button type="button" :class="classes" @click="onClick" :style="style">{{ label }}</button>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import './buttonStorybook.css'; import './buttonStorybook.css';
import { computed } from 'vue'; import { computed } from 'vue';
const props = withDefaults(defineProps<{ const props = withDefaults(
/** defineProps<{
* The label of the button /**
*/ * The label of the button
label: string, */
/** label: string;
* primary or secondary button /**
*/ * primary or secondary button
primary?: boolean, */
/** primary?: boolean;
* size of the button /**
*/ * size of the button
size?: 'small' | 'medium' | 'large', */
/** size?: 'small' | 'medium' | 'large';
* background color of the button /**
*/ * background color of the button
backgroundColor?: string, */
backgroundColor?: string;
}>(), { primary: false }); }>(),
{ primary: false },
);
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'click', id: number): void; (e: 'click', id: number): void;
...@@ -38,11 +40,10 @@ const classes = computed(() => ({ ...@@ -38,11 +40,10 @@ const classes = computed(() => ({
})); }));
const style = computed(() => ({ const style = computed(() => ({
backgroundColor: props.backgroundColor backgroundColor: props.backgroundColor,
})); }));
const onClick = () => { const onClick = () => {
emit("click", 1) emit('click', 1);
}; };
</script> </script>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment