From e3d5451d9ae8058bdd721d9163b33c0489676539 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: Wed, 18 Dec 2024 11:23:19 +0500
Subject: [PATCH 1/4] feat: component "Popup"

---
 README.md                                     |  6 +-
 src/App.vue                                   | 23 ++++++
 src/common/interfaces/componentsProps.ts      |  8 +++
 src/stories/components/Button/Button.vue      |  2 +-
 src/stories/components/Popup/Popup.stories.ts | 72 +++++++++++++++++++
 src/stories/components/Popup/Popup.vue        | 71 ++++++++++++++++++
 6 files changed, 180 insertions(+), 2 deletions(-)
 create mode 100644 src/stories/components/Popup/Popup.stories.ts
 create mode 100644 src/stories/components/Popup/Popup.vue

diff --git a/README.md b/README.md
index 1976a8e..bf8163a 100644
--- a/README.md
+++ b/README.md
@@ -7,13 +7,17 @@
 ## Список компонентов:
 - TreeList;
 - MenuDial;
+- Popup;
 - Slider;
 - Drawer;
 - Modal;
 - SelectButton;
 - Button;
 - ToggleSwitch;
-- Divider;
+- Divider.
+
+## Components count: 10
+## Bundle size: 248.7KB
 
 ### Настройка окружения
 
diff --git a/src/App.vue b/src/App.vue
index 5838a25..d7bf047 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -111,6 +111,7 @@ import Slider from '@stories/components/Slider/Slider.vue';
 import type { ISBOption } from '@interfaces/componentsProp';
 import Modal from '@stories/components/Modal/Modal.vue';
 import MenuDial from '@stories/components/MenuDial/MenuDial.vue';
+import Popup from '@stories/components/Popup/Popup.vue';
 
 const gentleIcons = [
   Age18Icon,
@@ -282,10 +283,32 @@ const visible = ref(false);
 const onClose = () => console.log('close!');
 const value = ref();
 const active = ref(false);
+const popupActive = ref(false);
+const popupActive2 = ref(false);
 const sliderValue = ref(1);
 </script>
 
 <template>
+  <div class="hui" style="width: 500px; height: 500px; background-color: gray"></div>
+  <Popup v-model:active="popupActive" parentSelector=".hui" theme="sky">
+    <Button
+      @click="
+        () => {
+          popupActive = false;
+          visible = true;
+        }
+      "
+      label="Открыть модальное окно"
+    />
+  </Popup>
+  <Popup v-model:active="popupActive2" theme="sky"
+    >Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet fugiat harum maiores placeat
+    soluta, vel velit voluptas. Accusamus aut, error et minima neque praesentium, ratione,
+    reprehenderit repudiandae saepe ut vero! Lorem ipsum dolor sit amet, consectetur adipisicing
+    elit. Amet fugiat harum maiores placeat soluta, vel velit voluptas. Accusamus aut, error et
+    minima neque praesentium, ratione, reprehenderit repudiandae saepe ut vero!</Popup
+  >
+
   <Modal v-model:visible="visible" theme="red" @onClose="onClose"
     ><template #header>huuuuuuuuuuui</template>Lorem ipsum dolor sit amet, consectetur adipisicing
     elit. Eaque explicabo, facere fuga hic id impedit magnam maiores minima necessitatibus, nemo
diff --git a/src/common/interfaces/componentsProps.ts b/src/common/interfaces/componentsProps.ts
index 8d663ab..8a1459e 100644
--- a/src/common/interfaces/componentsProps.ts
+++ b/src/common/interfaces/componentsProps.ts
@@ -77,6 +77,14 @@ export interface IModalProps {
   headerDivider?: boolean;
 }
 
+export interface IPopupProps {
+  parentSelector?: string;
+  theme?: TThemeColor;
+  maxWidth?: string;
+  maxHeight?: string;
+  padding?: string;
+}
+
 export interface ISBProps {
   options: ISBOption[];
   size?: TSize;
diff --git a/src/stories/components/Button/Button.vue b/src/stories/components/Button/Button.vue
index cef4d55..be2e174 100644
--- a/src/stories/components/Button/Button.vue
+++ b/src/stories/components/Button/Button.vue
@@ -80,7 +80,7 @@ const width = computed(() => (props.width ? `${props.width}px` : 'max-content'))
 .button {
   position: relative;
   border-radius: 7px;
-  display: flex;
+  display: inline-flex;
   gap: 8px;
   justify-content: center;
   align-items: center;
diff --git a/src/stories/components/Popup/Popup.stories.ts b/src/stories/components/Popup/Popup.stories.ts
new file mode 100644
index 0000000..c8d3e5c
--- /dev/null
+++ b/src/stories/components/Popup/Popup.stories.ts
@@ -0,0 +1,72 @@
+import type { Meta, StoryObj } from '@storybook/vue3';
+
+import Popup from './Popup.vue';
+import Button from '@stories/components/Button/Button.vue';
+
+const meta: Meta = {
+  title: 'Components/Popup',
+  component: Popup,
+  tags: ['autodocs'],
+  parameters: {
+    docs: {
+      description: {
+        component: 'A component that is used as a Popup. Can be used with icon.',
+      },
+    },
+  },
+  argTypes: {
+    default: { control: 'text' },
+    parentSelector: { control: 'text' },
+    maxWidth: { control: 'text' },
+    maxHeight: { control: 'text' },
+    padding: { control: 'text' },
+    theme: {
+      control: 'select',
+      options: [
+        'white',
+        'slate',
+        'blue',
+        'sky',
+        'teal',
+        'green',
+        'yellow',
+        'orange',
+        'pink',
+        'fuchsia',
+        'purple',
+        'indigo',
+        'rose',
+        'red',
+        'black',
+      ],
+    },
+  },
+  args: {},
+} satisfies Meta<typeof Popup>;
+
+export default meta;
+
+type Story = StoryObj<typeof meta>;
+
+export const Primary: Story = {
+  args: {
+    default:
+      'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet fugiat harum maiores placeat\n    soluta, vel velit voluptas. Accusamus aut, error et minima neque praesentium, ratione,\n    reprehenderit repudiandae saepe ut vero! Lorem ipsum dolor sit amet, consectetur adipisicing\n    elit. Amet fugiat harum maiores placeat soluta, vel velit voluptas. Accusamus aut, error et\n    minima neque praesentium, ratione, reprehenderit repudiandae saepe ut vero!',
+    maxWidth: '200px',
+    maxHeight: '100px',
+  },
+};
+
+export const Full: Story = {
+  render: (args) => ({
+    components: { Popup, Button },
+    setup() {
+      return { args };
+    },
+    template:
+      '<Popup v-bind="args"><Button label="Создать" theme="sky" /><p style="display: inline-block; padding: 0 30px"></p><Button label="Удалить" theme="red" /></Popup>',
+  }),
+  args: {
+    theme: 'black',
+  },
+};
diff --git a/src/stories/components/Popup/Popup.vue b/src/stories/components/Popup/Popup.vue
new file mode 100644
index 0000000..a9eb103
--- /dev/null
+++ b/src/stories/components/Popup/Popup.vue
@@ -0,0 +1,71 @@
+<script setup lang="ts">
+import type { IPopupProps } from '@interfaces/componentsProps';
+import { computed, ref } from 'vue';
+import { convert300ThemeToColor, convert500ThemeToColor } from '@helpers/colors';
+
+const props = withDefaults(defineProps<IPopupProps>(), {
+  parentSelector: 'body',
+  theme: 'white',
+  maxWidth: '300px',
+  maxHeight: '100px',
+  padding: '5px',
+});
+const active = defineModel<boolean>('active');
+const themeColor = computed(() => convert500ThemeToColor(props.theme));
+const scrollColor = computed(() => convert300ThemeToColor(props.theme));
+
+const top = ref();
+const left = ref();
+const isContainer = ref();
+
+const container = document.querySelector(props.parentSelector);
+if (container) {
+  container.addEventListener('pointerdown', (e) => {
+    if (e.button === 2) {
+      console.log('e.clientY, e.clientX ', e.clientY, e.clientX);
+      isContainer.value = true;
+      if (!active.value) active.value = true;
+      top.value = e.clientY;
+      left.value = e.clientX;
+      e.stopPropagation();
+    }
+  });
+  container.addEventListener('contextmenu', (e) => {
+    if (isContainer.value) e.preventDefault();
+  });
+}
+
+document.addEventListener('pointerdown', (e) => {
+  if (e.button === 0) active.value = false;
+});
+</script>
+
+<template>
+  <section
+    oncontextmenu="return false"
+    id="popup"
+    @pointerdown.stop=""
+    :style="`top: ${top}px; left: ${left}px; opacity: ${active ? 1 : 0}; pointer-events: ${active ? 'auto' : 'none'}; padding: ${padding}`"
+  >
+    <div :style="`max-width: ${maxWidth}; max-height: ${maxHeight}; overflow: auto;`">
+      <slot />
+      <p v-if="!$slots.default" style="background-color: black; color: white; padding: 10px">
+        Popup
+      </p>
+    </div>
+  </section>
+</template>
+
+<style scoped>
+#popup {
+  position: fixed;
+  transition: opacity 0.2s ease-in-out;
+  background-color: v-bind(themeColor);
+  border: 1px solid #403e46;
+  border-radius: 5px;
+}
+::-webkit-scrollbar-thumb {
+  border-radius: 5px;
+  background-color: v-bind(scrollColor);
+}
+</style>
-- 
GitLab


From a8c3443a36a6f470bc64d092ac76eacc346e82a4 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: Wed, 18 Dec 2024 17:11:04 +0500
Subject: [PATCH 2/4] refactor: favicon

---
 .storybook/manager-head.html |   2 +-
 index.html                   |   2 +-
 public/storybook.ico         | Bin 218174 -> 0 bytes
 public/storybook.svg         |   1 +
 4 files changed, 3 insertions(+), 2 deletions(-)
 delete mode 100644 public/storybook.ico
 create mode 100644 public/storybook.svg

diff --git a/.storybook/manager-head.html b/.storybook/manager-head.html
index 657a1b8..2634a89 100644
--- a/.storybook/manager-head.html
+++ b/.storybook/manager-head.html
@@ -2,7 +2,7 @@
 <html lang="en">
 <head>
   <meta charset="UTF-8">
-  <link rel="icon" href="./storybook.ico">
+  <link rel="icon" href="./storybook.svg">
   <title>Storybook</title>
 </head>
 <body>
diff --git a/index.html b/index.html
index 0ab5bb4..dcb9d19 100644
--- a/index.html
+++ b/index.html
@@ -2,7 +2,7 @@
 <html lang="">
   <head>
     <meta charset="UTF-8">
-    <link rel="icon" href="/storybook.ico">
+    <link rel="icon" href="/storybook.svg">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>UI Storybook</title>
   </head>
diff --git a/public/storybook.ico b/public/storybook.ico
deleted file mode 100644
index 690ee543d1b7a8d727252f9d278e2538ad02a61f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 218174
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

diff --git a/public/storybook.svg b/public/storybook.svg
new file mode 100644
index 0000000..63075c1
--- /dev/null
+++ b/public/storybook.svg
@@ -0,0 +1 @@
+<svg height="319" preserveAspectRatio="xMidYMid" viewBox="0 0 256 319" width="256" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="a" d="m9.87245893 293.324145-9.86099779-262.7509283c-.3256701-8.6776325 6.32802782-16.0318249 14.99485846-16.5735018l223.4880694-13.96800436c8.821799-.55136241 16.420248 6.15315109 16.971611 14.97495016.020773.3323713.031167.6653101.031167.99833v286.3136053c0 8.839012-7.165435 16.004447-16.004448 16.004447-.239453 0-.478875-.005374-.718087-.016117l-213.6270715-9.594673c-8.3199296-.373675-14.9627611-7.06565-15.27510157-15.388108z"/><mask id="b" fill="#fff"><use fill="#fff" xlink:href="#a"/></mask></defs><use fill="#ff4785" xlink:href="#a"/><path d="m188.665358 39.126973 1.526545-36.71548766 30.691632-2.41148534 1.32222 37.8634126c.046016 1.317734-.984915 2.423272-2.302649 2.4692883-.564237.0197036-1.117199-.1611913-1.560697-.5105633l-11.83568-9.323726-14.013155 10.6298328c-1.050497.7968662-2.548081.5912577-3.344947-.4592396-.335442-.4422072-.506327-.9874722-.483269-1.5420318zm-39.251655 80.853336c0 6.226666 41.941975 3.242387 47.572316-1.131416 0-42.4021104-22.751978-64.6837519-64.414689-64.6837519-41.6627118 0-65.0056495 22.6283131-65.0056495 56.5707999 0 59.116499 79.7796605 60.247915 79.7796605 92.493278 0 9.05133-4.432203 14.425558-14.18305 14.425558-12.70565 0-17.728814-6.488863-17.137853-28.551479 0-4.786197-48.4587575-6.278336-49.9361587 0-3.7620647 53.465572 29.5480226 68.887096 67.6649717 68.887096 36.935028 0 65.89209-19.687271 65.89209-55.326883 0-63.359309-80.961582-61.662185-80.961582-93.058985 0-12.7284338 9.455368-14.425558 15.069492-14.425558 5.909604 0 16.546892 1.0415999 15.660452 24.801341z" fill="#fff" mask="url(#b)"/></svg>
\ No newline at end of file
-- 
GitLab


From ea28f7472cb7a70cb0401fa29cfb6c0324c03641 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: Wed, 18 Dec 2024 17:26:33 +0500
Subject: [PATCH 3/4] docs: edit README.md

---
 README.md | 47 +++++++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md
index bf8163a..0866e44 100644
--- a/README.md
+++ b/README.md
@@ -16,29 +16,40 @@
 - ToggleSwitch;
 - Divider.
 
-## Components count: 10
-## Bundle size: 248.7KB
-
-### Настройка окружения
-
+---
+## Общая информация
+### Components count: 10
+### Bundle size: 254.6KB
+---
+## Важные моменты при разработке
+### Общее начало шаблона для компонентов:
+```  
+const props = withDefaults(defineProps<IProps>(), {  
+   
+});    
+const emit = defineEmits(['']);  
+const visible = defineModel('');  
+watch(, () => {});  
+const computed = computed(() => );  
+```
+- I*Componentname*Props вместо ```IProps```;
+- watchers после defineModel;
+- далее - computeds;
+- затем - функции (handlers).
+### После создания иконки:
+1. Добавить иконку в iconsSet (src/common/constants/icons);
+2. Добавить иконку в соответствующий массив в App.vue.
+---
+## Настройка окружения
+### Установка зависимостей:
 ```sh
 yarn
 ```
-
-### Просмотр существующих иконок в виде списка и тестирование компонентов
-
+### Просмотр существующих иконок в виде списка и тестирование компонентов:
 ```sh
 yarn dev
 ```
-
-### Проверка типов, компиляция и минимизация для production
-
+### Проверка типов, компиляция и минимизация для production:
 ```sh
 yarn build
-```
-
-## Важные моменты при разработке
-
-После создания иконки:
-1. Добавить иконку в iconsSet (src/common/constants/icons);
-2. Добавить иконку в соответствующий массив в App.vue.
\ No newline at end of file
+```
\ No newline at end of file
-- 
GitLab


From cfe12013d0a726c69fed391f129560b765606598 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: Wed, 18 Dec 2024 17:30:42 +0500
Subject: [PATCH 4/4] refactor: change color logic and fix some problems of
 components

---
 src/App.vue                                   |   4 +-
 src/assets/main.css                           |   9 +
 src/common/helpers/colors.ts                  | 276 +++++++++++++++++-
 src/common/helpers/common.ts                  |  28 ++
 src/common/interfaces/common.ts               |  10 +-
 src/common/interfaces/componentsProp.ts       |  22 +-
 src/common/interfaces/componentsProps.ts      |  39 ++-
 .../components/Button/Button.stories.ts       |  12 +-
 src/stories/components/Button/Button.vue      |  15 +-
 .../components/Divider/Divider.stories.ts     |   3 +-
 src/stories/components/Divider/Divider.vue    |   5 +-
 .../components/Drawer/Drawer.stories.ts       |   3 +-
 src/stories/components/Drawer/Drawer.vue      |  35 ++-
 .../components/MenuDial/MenuDial.stories.ts   |  53 +++-
 src/stories/components/MenuDial/MenuDial.vue  |  24 +-
 src/stories/components/Modal/Modal.stories.ts |   3 +-
 src/stories/components/Modal/Modal.vue        |  31 +-
 src/stories/components/Popup/Popup.stories.ts |   3 +-
 src/stories/components/Popup/Popup.vue        |  33 ++-
 .../SelectButton/SelectButton.stories.ts      |  13 +-
 .../components/SelectButton/SelectButton.vue  |  22 +-
 .../components/Slider/Slider.stories.ts       |   9 +-
 src/stories/components/Slider/Slider.vue      |  14 +-
 .../ToggleSwitch/ToggleSwitch.stories.ts      |  14 +-
 .../components/ToggleSwitch/ToggleSwitch.vue  |  11 +-
 src/stories/components/TreeList/TreeItems.vue |  12 +-
 .../components/TreeList/TreeList.stories.ts   |   6 +-
 src/stories/components/TreeList/TreeList.vue  |  11 +-
 28 files changed, 592 insertions(+), 128 deletions(-)
 create mode 100644 src/common/helpers/common.ts

diff --git a/src/App.vue b/src/App.vue
index d7bf047..ad430e4 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -108,7 +108,7 @@ import ToggleSwitch from '@stories/components/ToggleSwitch/ToggleSwitch.vue';
 import TriangleIcon from '@stories/icons/Mono/TriangleIcon.vue';
 import Button from '@stories/components/Button/Button.vue';
 import Slider from '@stories/components/Slider/Slider.vue';
-import type { ISBOption } from '@interfaces/componentsProp';
+import type { ISBOption, ISliderOptions } from '@interfaces/componentsProp';
 import Modal from '@stories/components/Modal/Modal.vue';
 import MenuDial from '@stories/components/MenuDial/MenuDial.vue';
 import Popup from '@stories/components/Popup/Popup.vue';
@@ -219,7 +219,7 @@ const gentleIcons = [
   UserIcon,
 ];
 const visibleDrawer = ref(true);
-const sliderOptions = [
+const sliderOptions: ISliderOptions[] = [
   {
     label: 0,
     value: 0,
diff --git a/src/assets/main.css b/src/assets/main.css
index 7b91d0d..21b455a 100644
--- a/src/assets/main.css
+++ b/src/assets/main.css
@@ -82,6 +82,15 @@
   --teal-700: #0f766e;
   --teal-800: #115e59;
   --teal-900: #134e4a;
+  --cyan-100: #cffafe;
+  --cyan-200: #a5f3fc;
+  --cyan-300: #67e8f9;
+  --cyan-400: #22d3ee;
+  --cyan-500: #06b6d4;
+  --cyan-600: #0891b2;
+  --cyan-700: #0e7490;
+  --cyan-800: #155e75;
+  --cyan-900: #164e63;
   --sky-100: #e0f2fe;
   --sky-200: #bae6fd;
   --sky-300: #7dd3fc;
diff --git a/src/common/helpers/colors.ts b/src/common/helpers/colors.ts
index 5ec5279..74a597b 100644
--- a/src/common/helpers/colors.ts
+++ b/src/common/helpers/colors.ts
@@ -1,13 +1,106 @@
-export const convert300ThemeToColor = (theme: string | undefined) => {
+import type { TDarkness, TThemeColor } from '@interfaces/common';
+
+export const convertWhiteOrBlackToColor = (theme: 'white' | 'black', darkness: TDarkness) => {
+  if (theme === 'white') {
+    if (darkness === 500 || darkness === 400 || darkness === 600) return '#cbd5e1';
+    if (darkness === 300 || darkness === 700) return '#94a3b8';
+    if (darkness === 200 || darkness === 800) return '#f1f5f9';
+    if (darkness === 100 || darkness === 900) return '#e2e8f0';
+  }
+  if (darkness === 500 || darkness === 400 || darkness === 600) return '#475569';
+  if (darkness === 300 || darkness === 700) return '#64748b';
+  if (darkness === 200 || darkness === 800) return '#94a3b8';
+  if (darkness === 100 || darkness === 900) return '#cbd5e1';
+};
+
+export const convert100ThemeToColor = (theme: TThemeColor) => {
+  switch (theme) {
+    case 'white':
+      return '#9ca3af';
+    case 'blue':
+      return '#dbeafe';
+    case 'sky':
+      return '#e0f2fe';
+    case 'cyan':
+      return '#cffafe';
+    case 'teal':
+      return '#ccfbf1';
+    case 'lime':
+      return '#ecfccb';
+    case 'green':
+      return '#dcfce7';
+    case 'yellow':
+      return '#fef9c3';
+    case 'amber':
+      return '#fef3c7';
+    case 'orange':
+      return '#ffedd5';
+    case 'pink':
+      return '#fce7f3';
+    case 'fuchsia':
+      return '#fae8ff';
+    case 'purple':
+      return '#f3e8ff';
+    case 'indigo':
+      return '#e0e7ff';
+    case 'rose':
+      return '#ffe4e6';
+    case 'red':
+      return '#fee2e2';
+    case 'black':
+      return '#4b5563';
+  }
+};
+
+export const convert200ThemeToColor = (theme: TThemeColor) => {
   switch (theme) {
     case 'white':
-      return '#cbd5e1';
-    case 'slate':
-      return '#cbd5e1';
+      return '#d1d5db';
+    case 'blue':
+      return '#bfdbfe';
+    case 'sky':
+      return '#bae6fd';
+    case 'cyan':
+      return '#a5f3fc';
+    case 'teal':
+      return '#99f6e4';
+    case 'lime':
+      return '#d9f99d';
+    case 'green':
+      return '#bbf7d0';
+    case 'yellow':
+      return '#fef08a';
+    case 'amber':
+      return '#fde68a';
+    case 'orange':
+      return '#fed7aa';
+    case 'pink':
+      return '#fbcfe8';
+    case 'fuchsia':
+      return '#f5d0fe';
+    case 'purple':
+      return '#e9d5ff';
+    case 'indigo':
+      return '#c7d2fe';
+    case 'rose':
+      return '#fecdd3';
+    case 'red':
+      return '#fecaca';
+    case 'black':
+      return '#374151';
+  }
+};
+
+export const convert300ThemeToColor = (theme: TThemeColor) => {
+  switch (theme) {
+    case 'white':
+      return '#e5e7eb';
     case 'blue':
       return '#93c5fd';
     case 'sky':
       return '#7dd3fc';
+    case 'cyan':
+      return '#67e8f9';
     case 'teal':
       return '#5eead4';
     case 'lime':
@@ -33,20 +126,59 @@ export const convert300ThemeToColor = (theme: string | undefined) => {
     case 'red':
       return '#fca5a5';
     case 'black':
-      return '#334155';
+      return '#1f2937';
+  }
+};
+
+export const convert400ThemeToColor = (theme: TThemeColor) => {
+  switch (theme) {
+    case 'white':
+      return '#f3f4f6';
+    case 'blue':
+      return '#60a5fa';
+    case 'sky':
+      return '#38bdf8';
+    case 'cyan':
+      return '#22d3ee';
+    case 'teal':
+      return '#2dd4bf';
+    case 'lime':
+      return '#a3e635';
+    case 'green':
+      return '#4ade80';
+    case 'yellow':
+      return '#facc15';
+    case 'amber':
+      return '#fbbf24';
+    case 'orange':
+      return '#fb923c';
+    case 'pink':
+      return '#f472b6';
+    case 'fuchsia':
+      return '#e879f9';
+    case 'purple':
+      return '#c084fc';
+    case 'indigo':
+      return '#818cf8';
+    case 'rose':
+      return '#fb7185';
+    case 'red':
+      return '#f87171';
+    case 'black':
+      return '#111827';
   }
 };
 
-export const convert500ThemeToColor = (theme: string | undefined) => {
+export const convert500ThemeToColor = (theme: TThemeColor) => {
   switch (theme) {
     case 'white':
       return '#ffffff';
-    case 'slate':
-      return '#64748b';
     case 'blue':
       return '#3b82f6';
     case 'sky':
       return '#0ea5e9';
+    case 'cyan':
+      return '#06b6d4';
     case 'teal':
       return '#14b8a6';
     case 'lime':
@@ -74,19 +206,96 @@ export const convert500ThemeToColor = (theme: string | undefined) => {
     case 'black':
       return '#000000';
   }
-  return '#000000';
 };
 
-export const convert800ThemeToColor = (theme: string | undefined) => {
+export const convert600ThemeToColor = (theme: TThemeColor) => {
   switch (theme) {
     case 'white':
-      return '#ffffff';
-    case 'slate':
-      return '#1e293b';
+      return '#f3f4f6';
+    case 'blue':
+      return '#2563eb';
+    case 'sky':
+      return '#0284c7';
+    case 'cyan':
+      return '#0891b2';
+    case 'teal':
+      return '#0d9488';
+    case 'lime':
+      return '#65a30d';
+    case 'green':
+      return '#16a34a';
+    case 'yellow':
+      return '#ca8a04';
+    case 'amber':
+      return '#d97706';
+    case 'orange':
+      return '#ea580c';
+    case 'pink':
+      return '#db2777';
+    case 'fuchsia':
+      return '#c026d3';
+    case 'purple':
+      return '#9333ea';
+    case 'indigo':
+      return '#4f46e5';
+    case 'rose':
+      return '#e11d48';
+    case 'red':
+      return '#dc2626';
+    case 'black':
+      return '#111827';
+  }
+};
+
+export const convert700ThemeToColor = (theme: TThemeColor) => {
+  switch (theme) {
+    case 'white':
+      return '#e5e7eb';
+    case 'blue':
+      return '#1d4ed8';
+    case 'sky':
+      return '#0369a1';
+    case 'cyan':
+      return '#0e7490';
+    case 'teal':
+      return '#0f766e';
+    case 'lime':
+      return '#4d7c0f';
+    case 'green':
+      return '#15803d';
+    case 'yellow':
+      return '#a16207';
+    case 'amber':
+      return '#b45309';
+    case 'orange':
+      return '#c2410c';
+    case 'pink':
+      return '#be185d';
+    case 'fuchsia':
+      return '#a21caf';
+    case 'purple':
+      return '#7e22ce';
+    case 'indigo':
+      return '#4338ca';
+    case 'rose':
+      return '#be123c';
+    case 'red':
+      return '#b91c1c';
+    case 'black':
+      return '#1f2937';
+  }
+};
+
+export const convert800ThemeToColor = (theme: TThemeColor) => {
+  switch (theme) {
+    case 'white':
+      return '#d1d5db';
     case 'blue':
       return '#1e40af';
     case 'sky':
       return '#075985';
+    case 'cyan':
+      return '#155e75';
     case 'teal':
       return '#115e59';
     case 'lime':
@@ -112,6 +321,45 @@ export const convert800ThemeToColor = (theme: string | undefined) => {
     case 'red':
       return '#991b1b';
     case 'black':
-      return '#000000';
+      return '#374151';
+  }
+};
+
+export const convert900ThemeToColor = (theme: TThemeColor) => {
+  switch (theme) {
+    case 'white':
+      return '#9ca3af';
+    case 'blue':
+      return '#1e3a8a';
+    case 'sky':
+      return '#0c4a6e';
+    case 'cyan':
+      return '#164e63';
+    case 'teal':
+      return '#134e4a';
+    case 'lime':
+      return '#365314';
+    case 'green':
+      return '#14532d';
+    case 'yellow':
+      return '#713f12';
+    case 'amber':
+      return '#78350f';
+    case 'orange':
+      return '#7c2d12';
+    case 'pink':
+      return '#831843';
+    case 'fuchsia':
+      return '#701a75';
+    case 'purple':
+      return '#581c87';
+    case 'indigo':
+      return '#312e81';
+    case 'rose':
+      return '#881337';
+    case 'red':
+      return '#7f1d1d';
+    case 'black':
+      return '#4b5563';
   }
 };
diff --git a/src/common/helpers/common.ts b/src/common/helpers/common.ts
new file mode 100644
index 0000000..e4ec1fb
--- /dev/null
+++ b/src/common/helpers/common.ts
@@ -0,0 +1,28 @@
+import type { TDarkness, TThemeColor } from '@interfaces/common';
+import {
+  convert100ThemeToColor,
+  convert200ThemeToColor,
+  convert300ThemeToColor,
+  convert400ThemeToColor,
+  convert500ThemeToColor,
+  convert600ThemeToColor,
+  convert700ThemeToColor,
+  convert800ThemeToColor,
+  convert900ThemeToColor,
+} from '@helpers/colors';
+
+export const convertThemeToColor = (
+  theme: TThemeColor,
+  darkness: TDarkness | number = 500,
+): string => {
+  if (darkness === 500) return convert500ThemeToColor(theme);
+  if (darkness === 100) return convert100ThemeToColor(theme);
+  if (darkness === 200) return convert200ThemeToColor(theme);
+  if (darkness === 300) return convert300ThemeToColor(theme);
+  if (darkness === 400) return convert400ThemeToColor(theme);
+  if (darkness === 600) return convert600ThemeToColor(theme);
+  if (darkness === 700) return convert700ThemeToColor(theme);
+  if (darkness === 800) return convert800ThemeToColor(theme);
+  if (darkness === 900) return convert900ThemeToColor(theme);
+  return convert500ThemeToColor(theme);
+};
diff --git a/src/common/interfaces/common.ts b/src/common/interfaces/common.ts
index 7ff7e70..6a854a8 100644
--- a/src/common/interfaces/common.ts
+++ b/src/common/interfaces/common.ts
@@ -1,13 +1,17 @@
 import type { iconsSet } from '@/common/constants/icons';
 
+export type TIcons = keyof typeof iconsSet;
+
 export type TThemeColor =
   | 'white'
-  | 'slate'
   | 'blue'
   | 'sky'
+  | 'cyan'
   | 'teal'
+  | 'lime'
   | 'green'
   | 'yellow'
+  | 'amber'
   | 'orange'
   | 'pink'
   | 'fuchsia'
@@ -17,6 +21,8 @@ export type TThemeColor =
   | 'red'
   | 'black';
 
+export type TDarkness = 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
+
 export type TThemeColorNoWhite = Exclude<TThemeColor, 'white'>;
 
 export type TSize = 'small' | 'medium' | 'large' | 'huge';
@@ -30,5 +36,3 @@ export type TPosition = 'top' | 'right' | 'bottom' | 'left';
 export type TExpandedPosition = TPosition | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
 
 export type TBorder = 'solid' | 'dashed' | 'dotted';
-
-export type TIcons = keyof typeof iconsSet;
diff --git a/src/common/interfaces/componentsProp.ts b/src/common/interfaces/componentsProp.ts
index 1f0e3c3..aa30d5c 100644
--- a/src/common/interfaces/componentsProp.ts
+++ b/src/common/interfaces/componentsProp.ts
@@ -1,4 +1,4 @@
-import type { TIcons, TPosition, TTextStyle, TThemeColor } from '@interfaces/common';
+import type { TDarkness, TIcons, TPosition, TTextStyle, TThemeColor } from '@interfaces/common';
 
 export interface ITreeItem {
   label: string;
@@ -11,22 +11,38 @@ export interface ITreeItem {
   iconAfter?: TIcons;
   iconColor?: TThemeColor;
   children?: ITreeItem[];
+  darknessColor?: TDarkness;
+  darknessIconColor?: TDarkness;
   isLinkClicked?: boolean;
 }
 
+export interface IMDItemProps {
+  label: string;
+  theme?: TThemeColor;
+  darknessTheme?: TDarkness;
+  textStyle?: TTextStyle;
+  link?: string;
+  linkBlank?: boolean;
+  onClick?: () => void;
+}
+
 export interface ISBOption {
   label: string;
   value?: never;
   color?: TThemeColor;
   activeColor?: TThemeColor;
   backgroundColor?: TThemeColor;
+  darknessColor?: TDarkness;
+  darknessActiveColor?: TDarkness;
+  darknessBackgroundColor?: TDarkness;
   isLabelHidden?: boolean;
   iconPosition?: TPosition;
   textStyle?: TTextStyle;
 }
 
 export interface ISliderOptions {
-  label: string | number;
+  label: string | number | boolean;
   value?: string | number;
-  color?: string;
+  color?: TThemeColor;
+  darknessColor?: TDarkness;
 }
diff --git a/src/common/interfaces/componentsProps.ts b/src/common/interfaces/componentsProps.ts
index 8a1459e..c80425a 100644
--- a/src/common/interfaces/componentsProps.ts
+++ b/src/common/interfaces/componentsProps.ts
@@ -1,5 +1,6 @@
 import type {
   TBorder,
+  TDarkness,
   TDirection,
   TExpandedPosition,
   TIcons,
@@ -9,13 +10,19 @@ import type {
   TThemeColor,
   TThemeColorNoWhite,
 } from '@interfaces/common';
-import type { ISBOption, ISliderOptions, ITreeItem } from '@interfaces/componentsProp';
+import type {
+  IMDItemProps,
+  ISBOption,
+  ISliderOptions,
+  ITreeItem,
+} from '@interfaces/componentsProp';
 
 export interface ITLProps {
   items: ITreeItem[];
   maxWidth?: number;
   expand?: boolean;
   theme?: TThemeColor;
+  darknessTheme?: TDarkness;
 }
 
 export interface ITIProps {
@@ -24,21 +31,15 @@ export interface ITIProps {
     label: string;
   }[];
   items: ITreeItem[];
-  textColor: TThemeColor;
+  textColor: string;
   themeColor: string;
 }
 
 export interface IMDProps {
-  items: {
-    label: string;
-    theme?: string;
-    textStyle?: TTextStyle;
-    link?: string;
-    linkBlank?: boolean;
-    onClick?: () => void;
-  }[];
+  items: IMDItemProps[];
   size?: TSize;
-  theme?: string;
+  theme?: TThemeColor;
+  darknessTheme?: TDarkness;
   direction?: TDirection;
   // direction?: TDirection | 'circle';
 }
@@ -51,6 +52,8 @@ export interface ISliderProps {
   size?: TSize;
   theme?: TThemeColor;
   backgroundColor?: TThemeColor;
+  darknessTheme?: TDarkness;
+  darknessBackgroundColor?: TDarkness;
   orientation?: 'horizontal' | 'vertical';
   isSmooth?: boolean;
   options?: ISliderOptions[];
@@ -60,6 +63,7 @@ export interface IDrawerProps {
   position?: TPosition;
   width?: string | number;
   theme?: TThemeColor;
+  darknessTheme?: TDarkness;
   modal?: boolean;
   dismissible?: boolean;
   closeIcon?: TIcons;
@@ -69,6 +73,7 @@ export interface IDrawerProps {
 
 export interface IModalProps {
   theme?: TThemeColor;
+  darknessTheme?: TDarkness;
   width?: string;
   height?: string;
   position?: TExpandedPosition;
@@ -80,6 +85,7 @@ export interface IModalProps {
 export interface IPopupProps {
   parentSelector?: string;
   theme?: TThemeColor;
+  darknessTheme?: TDarkness;
   maxWidth?: string;
   maxHeight?: string;
   padding?: string;
@@ -91,6 +97,8 @@ export interface ISBProps {
   rounded?: boolean;
   activeBackgroundColor?: TThemeColor;
   border?: TThemeColor;
+  darknessActiveBackgroundColor?: TDarkness;
+  darknessBorder?: TDarkness;
   disabled?: boolean;
 }
 
@@ -100,17 +108,21 @@ export interface IButtonProps {
   textStyle?: TTextStyle;
   iconPos?: TPosition;
   width?: string | number;
+  iconOnly?: boolean;
   theme?: TThemeColor;
   textColor?: TThemeColor;
   border?: TThemeColor;
-  iconOnly?: boolean;
+  darknessTheme?: TDarkness;
+  darknessTextColor?: TDarkness;
+  darknessBorder?: TDarkness;
 }
 
 export interface ITSProps {
   size?: TSize;
   theme?: TThemeColorNoWhite;
   negativeTheme?: TThemeColor;
-  darkNegative?: boolean;
+  darknessTheme?: TDarkness;
+  darknessNegativeTheme?: TDarkness;
   disabled?: boolean;
 }
 
@@ -118,4 +130,5 @@ export interface IDividerProps {
   height?: number;
   type?: TBorder;
   color?: TThemeColor;
+  darknessColor?: TDarkness;
 }
diff --git a/src/stories/components/Button/Button.stories.ts b/src/stories/components/Button/Button.stories.ts
index bdbacf4..337bc5b 100644
--- a/src/stories/components/Button/Button.stories.ts
+++ b/src/stories/components/Button/Button.stories.ts
@@ -19,13 +19,19 @@ const meta: Meta = {
     textStyle: { control: 'select', options: ['bold', 'italic'] },
     iconPos: { control: 'select', options: ['left', 'top', 'right', 'bottom'] },
     width: { control: 'text' },
+    darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
+    darknessTextColor: {
+      control: 'select',
+      options: [100, 200, 300, 400, 500, 600, 700, 800, 900],
+    },
+    darknessBorder: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
     theme: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -43,9 +49,9 @@ const meta: Meta = {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -63,9 +69,9 @@ const meta: Meta = {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
diff --git a/src/stories/components/Button/Button.vue b/src/stories/components/Button/Button.vue
index be2e174..45df8f5 100644
--- a/src/stories/components/Button/Button.vue
+++ b/src/stories/components/Button/Button.vue
@@ -1,18 +1,25 @@
 <script setup lang="ts">
 import { computed } from 'vue';
-import { convert500ThemeToColor } from '@helpers/colors';
 import type { IButtonProps } from '@interfaces/componentsProps';
+import { convertThemeToColor } from '@helpers/common';
 
 const props = withDefaults(defineProps<IButtonProps>(), {
   size: 'medium',
   theme: 'white',
   textColor: 'black',
   iconPos: 'left',
+  darknessTheme: 500,
+  darknessTextColor: 500,
+  darknessBorder: 500,
 });
 
-const themeColor = computed(() => convert500ThemeToColor(props.theme));
-const textColorComputed = computed(() => convert500ThemeToColor(props.textColor));
-const borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : ''));
+const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
+const textColorComputed = computed(() =>
+  convertThemeToColor(props.textColor, props.darknessTextColor),
+);
+const borderColor = computed(() =>
+  !props.border ? '' : convertThemeToColor(props.border, props.darknessBorder),
+);
 const textSize = computed(() => {
   switch (props.size) {
     case 'small':
diff --git a/src/stories/components/Divider/Divider.stories.ts b/src/stories/components/Divider/Divider.stories.ts
index b7a6350..960e6f5 100644
--- a/src/stories/components/Divider/Divider.stories.ts
+++ b/src/stories/components/Divider/Divider.stories.ts
@@ -16,13 +16,14 @@ const meta: Meta = {
   argTypes: {
     height: { control: 'number' },
     type: { control: 'select', options: ['solid', 'dashed', 'dotted'] },
+    darknessColor: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
     color: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
diff --git a/src/stories/components/Divider/Divider.vue b/src/stories/components/Divider/Divider.vue
index 54164cd..b195e97 100644
--- a/src/stories/components/Divider/Divider.vue
+++ b/src/stories/components/Divider/Divider.vue
@@ -1,14 +1,15 @@
 <script setup lang="ts">
 import { computed } from 'vue';
-import { convert500ThemeToColor } from '@helpers/colors';
 import type { IDividerProps } from '@interfaces/componentsProps';
+import { convertThemeToColor } from '@helpers/common';
 
 const props = withDefaults(defineProps<IDividerProps>(), {
   height: 1,
   type: 'solid',
   color: 'black',
+  darknessColor: 500,
 });
-const colorConverted = computed(() => convert500ThemeToColor(props.color));
+const colorConverted = computed(() => convertThemeToColor(props.color, props.darknessColor));
 </script>
 
 <template>
diff --git a/src/stories/components/Drawer/Drawer.stories.ts b/src/stories/components/Drawer/Drawer.stories.ts
index cd0c0de..9cfdc30 100644
--- a/src/stories/components/Drawer/Drawer.stories.ts
+++ b/src/stories/components/Drawer/Drawer.stories.ts
@@ -26,13 +26,14 @@ const meta: Meta = {
     closeIcon: { control: 'select', options: Object.keys(iconsSet) },
     headerDivider: { control: 'boolean' },
     footerDivider: { control: 'boolean' },
+    darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
     theme: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
diff --git a/src/stories/components/Drawer/Drawer.vue b/src/stories/components/Drawer/Drawer.vue
index 913796f..1656f88 100644
--- a/src/stories/components/Drawer/Drawer.vue
+++ b/src/stories/components/Drawer/Drawer.vue
@@ -1,8 +1,9 @@
 <script setup lang="ts">
-import { computed } from 'vue';
+import { computed, watch } from 'vue';
 import { iconsSet } from '@/common/constants/icons';
-import { convert500ThemeToColor, convert300ThemeToColor } from '@helpers/colors';
+import { convertWhiteOrBlackToColor } from '@helpers/colors';
 import type { IDrawerProps } from '@interfaces/componentsProps';
+import { convertThemeToColor } from '@helpers/common';
 
 const props = withDefaults(defineProps<IDrawerProps>(), {
   visible: false,
@@ -11,25 +12,37 @@ const props = withDefaults(defineProps<IDrawerProps>(), {
   modal: true,
   dismissible: true,
   theme: 'white',
+  darknessTheme: 500,
   closeIcon: 'CrossIcon',
   headerDivider: false,
   footerDivider: false,
 });
+const body = document.querySelector('body')!;
 const emit = defineEmits(['onClose']);
 const visible = defineModel<boolean>('visible', {
   set(value) {
     if (!value) {
+      body.style.overflow = 'auto';
       emit('onClose');
     }
     return value;
   },
 });
-
-const themeColor = computed(() => convert500ThemeToColor(props.theme));
-const scrollColor = computed(() => convert300ThemeToColor(props.theme));
+watch(visible, () => {
+  if (visible.value) {
+    body.style.overflow = 'hidden';
+  }
+});
+const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
+const scrollAndBorderColor = computed(() =>
+  props.theme === 'white' || props.theme === 'black'
+    ? convertWhiteOrBlackToColor(props.theme, props.darknessTheme)
+    : convertThemeToColor(props.theme, 100 + ((props.darknessTheme + 600) % 900)),
+);
 const textColor = computed(() => {
-  if (!props.theme || props.theme === 'white') return 'black';
-  return 'white';
+  if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black'))
+    return '#000000';
+  return '#ffffff';
 });
 const drawerWidth = computed(() => {
   if (+props.width < 200) return '200px';
@@ -46,7 +59,7 @@ const drawerWidth = computed(() => {
           drawerBackgroundOpened: visible,
         },
       ]"
-      @click.prevent="dismissible ? (visible = false) : ''"
+      @pointerdown.stop="dismissible ? (visible = false) : ''"
     ></section>
     <section
       :style="`color: ${textColor}; background-color: ${themeColor}`"
@@ -108,7 +121,7 @@ const drawerWidth = computed(() => {
   justify-content: space-between;
   padding: 20px;
   transition: transform ease-out 0.2s;
-  border-right: 2px solid #b1b1b1;
+  border-right: 2px solid v-bind(scrollAndBorderColor);
 }
 .drawerVertical {
   width: 100vw !important;
@@ -158,7 +171,7 @@ const drawerWidth = computed(() => {
 }
 .divider {
   height: 2px;
-  background-color: v-bind(scrollColor);
+  background-color: v-bind(scrollAndBorderColor);
 }
 .divider-header {
   position: absolute;
@@ -176,6 +189,6 @@ const drawerWidth = computed(() => {
 }
 ::-webkit-scrollbar-thumb {
   border-radius: 5px;
-  background-color: v-bind(scrollColor);
+  background-color: v-bind(scrollAndBorderColor);
 }
 </style>
diff --git a/src/stories/components/MenuDial/MenuDial.stories.ts b/src/stories/components/MenuDial/MenuDial.stories.ts
index a91196a..1fb7c18 100644
--- a/src/stories/components/MenuDial/MenuDial.stories.ts
+++ b/src/stories/components/MenuDial/MenuDial.stories.ts
@@ -16,14 +16,15 @@ const meta: Meta = {
   argTypes: {
     items: { control: 'object' },
     size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] },
-    direction: { control: 'select', options: ['top', 'bottom', 'left', 'right'] },
+    direction: { control: 'select', options: ['up', 'down', 'left', 'right'] },
+    darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
     theme: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -79,3 +80,51 @@ export const Full: Story = {
     theme: 'sky',
   },
 };
+
+export const Down: Story = {
+  args: {
+    items: [
+      {
+        label: 'font-family link',
+        theme: 'green',
+        darknessTheme: 700,
+        link: 'https://developer.mozilla.org/en-US/docs/Web/CSS/font-family',
+        linkBlank: true,
+      },
+      {
+        label: 'Second',
+        theme: 'green',
+        darknessTheme: 800,
+        textStyle: 'italic',
+      },
+    ],
+    theme: 'red',
+    darknessTheme: 700,
+    direction: 'down',
+  },
+};
+
+export const Huge: Story = {
+  args: {
+    items: [
+      {
+        label: 'font-family link',
+        theme: 'green',
+        darknessTheme: 700,
+        link: 'https://developer.mozilla.org/en-US/docs/Web/CSS/font-family',
+        linkBlank: true,
+      },
+      {
+        label: 'Second',
+        theme: 'green',
+        darknessTheme: 800,
+        textStyle: 'italic',
+      },
+    ],
+
+    theme: 'red',
+    darknessTheme: 700,
+    direction: 'right',
+    size: 'medium',
+  },
+};
diff --git a/src/stories/components/MenuDial/MenuDial.vue b/src/stories/components/MenuDial/MenuDial.vue
index 5b54129..933d5f1 100644
--- a/src/stories/components/MenuDial/MenuDial.vue
+++ b/src/stories/components/MenuDial/MenuDial.vue
@@ -1,21 +1,29 @@
 <script setup lang="ts">
 import { computed } from 'vue';
 import type { IMDProps } from '@interfaces/componentsProps';
-import { convert500ThemeToColor } from '@helpers/colors';
 import PlusIcon from '@stories/icons/Mono/PlusIcon.vue';
+import { convertThemeToColor } from '@helpers/common';
+import { convertWhiteOrBlackToColor } from '@helpers/colors';
 
 const props = withDefaults(defineProps<IMDProps>(), {
   theme: 'white',
+  darknessTheme: 500,
   size: 'medium',
   direction: 'right',
 });
 const active = defineModel('active');
 
-const themeColor = computed(() => convert500ThemeToColor(props.theme));
+const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
 const textColor = computed(() => {
-  if (props.theme === 'white') return '#000000';
+  if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black'))
+    return '#000000';
   return '#ffffff';
 });
+const borderColor = computed(() =>
+  props.theme === 'white' || props.theme === 'black'
+    ? convertWhiteOrBlackToColor(props.theme, props.darknessTheme)
+    : convertThemeToColor(props.theme, 100 + ((props.darknessTheme + 600) % 900)),
+);
 const elementsSize = computed(() => {
   switch (props.size) {
     case 'small':
@@ -34,7 +42,7 @@ const menuListStyles = computed(() => {
     case 'up':
       return `flex-direction: column-reverse; transform: translateY(-${active.value ? (0.5 + props.items.length) * elementsSize.value + 15 : 1.5 * elementsSize.value}px) translateX(calc(-50% + ${elementsSize.value / 2}px))`;
     case 'down':
-      return `flex-direction: column; transform: translateY(${active.value ? 25 : -20}px) translateX(calc(-50% + ${elementsSize.value / 2}px))`;
+      return `flex-direction: column; transform: translateY(${active.value ? elementsSize.value / 1.75 : -20}px) translateX(calc(-50% + ${elementsSize.value / 2}px))`;
   }
   return `transform: translateY(-${elementsSize.value / 2}px) translateX(${active.value ? elementsSize.value + 10 : -20}px)`;
 });
@@ -60,7 +68,7 @@ const openLink = (url: string, isBlank: boolean | undefined) =>
 <template>
   <section class="menuContainer">
     <button
-      :style="`border: ${theme === 'white' ? '2px solid black' : ''}; background-color: ${themeColor ?? 'white'}; width: ${elementsSize}px; height: ${elementsSize}px; transform: ${active ? 'rotate(135deg)' : ''};`"
+      :style="`border: 2px solid ${borderColor}; background-color: ${themeColor ?? 'white'}; width: ${elementsSize}px; height: ${elementsSize}px; transform: ${active ? 'rotate(135deg)' : ''};`"
       class="menuButton"
       @click.prevent="active = !active"
     >
@@ -80,8 +88,8 @@ const openLink = (url: string, isBlank: boolean | undefined) =>
       <li
         v-for="(item, index) of items"
         :key="item.label"
-        :style="`height: ${elementsSize}px; background-color: ${convert500ThemeToColor(item.theme ?? 'white')};
-        color: ${!item.theme || item.theme === 'white' ? 'black' : 'white'}; border-color: ${!item.theme || item.theme === 'white' ? 'black' : 'white'};`"
+        :style="`height: ${elementsSize}px; background-color: ${convertThemeToColor(item.theme ?? 'white', item.darknessTheme ?? 500)};
+        color: ${item.theme === 'white' || ((item.darknessTheme ?? 500) <= 600 && item.theme !== 'black') ? 'black' : 'white'}; border-color: ${borderColor};`"
         class="menuElement"
         @click="
           () => {
@@ -147,7 +155,7 @@ const openLink = (url: string, isBlank: boolean | undefined) =>
   justify-content: center;
   align-items: center;
   padding: 10px;
-  border: 1px solid white;
+  border: 1px solid v-bind(borderColor);
   border-radius: 5px;
   user-select: none;
   cursor: pointer;
diff --git a/src/stories/components/Modal/Modal.stories.ts b/src/stories/components/Modal/Modal.stories.ts
index b23779a..d5c6d08 100644
--- a/src/stories/components/Modal/Modal.stories.ts
+++ b/src/stories/components/Modal/Modal.stories.ts
@@ -36,13 +36,14 @@ const meta: Meta = {
         'bottomRight',
       ],
     },
+    darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
     theme: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
diff --git a/src/stories/components/Modal/Modal.vue b/src/stories/components/Modal/Modal.vue
index 1ebe15a..5c8e74c 100644
--- a/src/stories/components/Modal/Modal.vue
+++ b/src/stories/components/Modal/Modal.vue
@@ -1,32 +1,45 @@
 <script setup lang="ts">
-import { computed } from 'vue';
-import { convert300ThemeToColor, convert500ThemeToColor } from '@helpers/colors';
+import { computed, watch } from 'vue';
+import { convertWhiteOrBlackToColor } from '@helpers/colors';
 import type { IModalProps } from '@interfaces/componentsProps';
 import { iconsSet } from '@/common/constants/icons';
+import { convertThemeToColor } from '@helpers/common';
 
 const props = withDefaults(defineProps<IModalProps>(), {
   visible: false,
   dismissible: false,
   theme: 'white',
+  darknessTheme: 500,
   width: '30%',
   height: '30%',
   headerDivider: false,
   closeIcon: 'CrossIcon',
 });
+const body = document.querySelector('body')!;
 const emit = defineEmits(['onClose']);
 const visible = defineModel('visible', {
   set(value) {
     if (!value) {
+      body.style.overflow = 'auto';
       emit('onClose');
     }
     return value;
   },
 });
-const themeColor = computed(() => convert500ThemeToColor(props.theme));
-const scrollColor = computed(() => convert300ThemeToColor(props.theme));
+watch(visible, () => {
+  if (visible.value) {
+    body.style.overflow = 'hidden';
+  }
+});
+const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
+const scrollAndBorderColor = computed(() =>
+  props.theme === 'white' || props.theme === 'black'
+    ? convertWhiteOrBlackToColor(props.theme, props.darknessTheme)
+    : convertThemeToColor(props.theme, 100 + ((props.darknessTheme + 600) % 900)),
+);
 const textColor = computed(() => {
-  if (!props.theme) return '#000000';
-  if (props.theme === 'white') return '#000000';
+  if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black'))
+    return '#000000';
   return '#ffffff';
 });
 const onKeydown = (event: KeyboardEvent) => {
@@ -101,7 +114,7 @@ document.addEventListener('keydown', onKeydown);
   min-width: 250px;
   min-height: 100px;
   padding: 20px;
-  border: 2px solid gray;
+  border: 2px solid v-bind(scrollAndBorderColor);
   border-radius: 15px;
   opacity: 0;
   transform: scale(0.5);
@@ -145,7 +158,7 @@ document.addEventListener('keydown', onKeydown);
 }
 .divider {
   height: 2px;
-  background-color: v-bind(scrollColor);
+  background-color: v-bind(scrollAndBorderColor);
   position: absolute;
   left: 20px;
   top: 60px;
@@ -153,7 +166,7 @@ document.addEventListener('keydown', onKeydown);
 }
 ::-webkit-scrollbar-thumb {
   border-radius: 5px;
-  background-color: v-bind(scrollColor);
+  background-color: v-bind(scrollAndBorderColor);
 }
 .toTop {
   top: 10px !important;
diff --git a/src/stories/components/Popup/Popup.stories.ts b/src/stories/components/Popup/Popup.stories.ts
index c8d3e5c..7f515ed 100644
--- a/src/stories/components/Popup/Popup.stories.ts
+++ b/src/stories/components/Popup/Popup.stories.ts
@@ -20,13 +20,14 @@ const meta: Meta = {
     maxWidth: { control: 'text' },
     maxHeight: { control: 'text' },
     padding: { control: 'text' },
+    darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
     theme: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
diff --git a/src/stories/components/Popup/Popup.vue b/src/stories/components/Popup/Popup.vue
index a9eb103..e199b8b 100644
--- a/src/stories/components/Popup/Popup.vue
+++ b/src/stories/components/Popup/Popup.vue
@@ -1,18 +1,31 @@
 <script setup lang="ts">
 import type { IPopupProps } from '@interfaces/componentsProps';
 import { computed, ref } from 'vue';
-import { convert300ThemeToColor, convert500ThemeToColor } from '@helpers/colors';
+import { convertThemeToColor } from '@helpers/common';
+import { convertWhiteOrBlackToColor } from '@helpers/colors';
 
 const props = withDefaults(defineProps<IPopupProps>(), {
   parentSelector: 'body',
   theme: 'white',
+  border: 'black',
   maxWidth: '300px',
   maxHeight: '100px',
   padding: '5px',
+  darknessTheme: 500,
+  darknessBorder: 500,
 });
 const active = defineModel<boolean>('active');
-const themeColor = computed(() => convert500ThemeToColor(props.theme));
-const scrollColor = computed(() => convert300ThemeToColor(props.theme));
+const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
+const scrollAndBorderColor = computed(() =>
+  props.theme === 'white' || props.theme === 'black'
+    ? convertWhiteOrBlackToColor(props.theme, props.darknessTheme)
+    : convertThemeToColor(props.theme, 100 + ((props.darknessTheme + 600) % 900)),
+);
+const textColor = computed(() => {
+  if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black'))
+    return '#000000';
+  return '#ffffff';
+});
 
 const top = ref();
 const left = ref();
@@ -20,9 +33,9 @@ const isContainer = ref();
 
 const container = document.querySelector(props.parentSelector);
 if (container) {
-  container.addEventListener('pointerdown', (e) => {
+  container.addEventListener('pointerdown', (event: Event) => {
+    const e = event as PointerEvent;
     if (e.button === 2) {
-      console.log('e.clientY, e.clientX ', e.clientY, e.clientX);
       isContainer.value = true;
       if (!active.value) active.value = true;
       top.value = e.clientY;
@@ -45,9 +58,11 @@ document.addEventListener('pointerdown', (e) => {
     oncontextmenu="return false"
     id="popup"
     @pointerdown.stop=""
-    :style="`top: ${top}px; left: ${left}px; opacity: ${active ? 1 : 0}; pointer-events: ${active ? 'auto' : 'none'}; padding: ${padding}`"
+    :style="`top: ${top}px; left: ${left}px; opacity: ${active ? 1 : 0}; pointer-events: ${active ? 'auto' : 'none'}; padding: ${padding}; color: ${textColor}`"
   >
-    <div :style="`max-width: ${maxWidth}; max-height: ${maxHeight}; overflow: auto;`">
+    <div
+      :style="`max-width: ${maxWidth}; max-height: ${maxHeight}; overflow: auto; padding-right: 5px`"
+    >
       <slot />
       <p v-if="!$slots.default" style="background-color: black; color: white; padding: 10px">
         Popup
@@ -61,11 +76,11 @@ document.addEventListener('pointerdown', (e) => {
   position: fixed;
   transition: opacity 0.2s ease-in-out;
   background-color: v-bind(themeColor);
-  border: 1px solid #403e46;
+  border: 1px solid v-bind(scrollAndBorderColor);
   border-radius: 5px;
 }
 ::-webkit-scrollbar-thumb {
   border-radius: 5px;
-  background-color: v-bind(scrollColor);
+  background-color: v-bind(scrollAndBorderColor);
 }
 </style>
diff --git a/src/stories/components/SelectButton/SelectButton.stories.ts b/src/stories/components/SelectButton/SelectButton.stories.ts
index 0e7f8c8..03c49b6 100644
--- a/src/stories/components/SelectButton/SelectButton.stories.ts
+++ b/src/stories/components/SelectButton/SelectButton.stories.ts
@@ -19,13 +19,21 @@ const meta: Meta = {
     },
     size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] },
     rounded: { control: 'boolean' },
+    darknessActiveBackgroundColor: {
+      control: 'select',
+      options: [100, 200, 300, 400, 500, 600, 700, 800, 900],
+    },
+    darknessBorder: {
+      control: 'select',
+      options: [100, 200, 300, 400, 500, 600, 700, 800, 900],
+    },
     activeBackgroundColor: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -43,9 +51,9 @@ const meta: Meta = {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -94,6 +102,7 @@ export const LargeFull: Story = {
       },
       {
         label: 'Second',
+        color: 'red',
         activeColor: 'blue',
         backgroundColor: 'yellow',
       },
diff --git a/src/stories/components/SelectButton/SelectButton.vue b/src/stories/components/SelectButton/SelectButton.vue
index 2f3761b..43ba74b 100644
--- a/src/stories/components/SelectButton/SelectButton.vue
+++ b/src/stories/components/SelectButton/SelectButton.vue
@@ -1,20 +1,25 @@
 <script setup lang="ts">
 import { computed } from 'vue';
-import { convert500ThemeToColor } from '@helpers/colors';
 import type { ISBProps } from '@interfaces/componentsProps';
+import { convertThemeToColor } from '@helpers/common';
 
 const props = withDefaults(defineProps<ISBProps>(), {
   size: 'medium',
-  border: 'black',
   activeBackgroundColor: 'sky',
+  darknessActiveBackgroundColor: 500,
+  darknessBorder: 500,
 });
 const emit = defineEmits(['onClick']);
 const value = defineModel<never>('value');
 
 const activeBackgroundColorComputed = computed(() =>
-  props.activeBackgroundColor ? convert500ThemeToColor(props.activeBackgroundColor) : '',
+  props.activeBackgroundColor
+    ? convertThemeToColor(props.activeBackgroundColor, props.darknessActiveBackgroundColor)
+    : '',
+);
+const borderColor = computed(() =>
+  !props.border ? '' : convertThemeToColor(props.border, props.darknessBorder),
 );
-const borderColor = computed(() => (props.border ? convert500ThemeToColor(props.border) : ''));
 const textSize = computed(() => {
   switch (props.size) {
     case 'small':
@@ -79,7 +84,7 @@ const buttonHeight = computed(() => {
       "
     >
       <span
-        :style="`background-color: ${activeBackgroundColorComputed && ((value && value === item.value) || value === item.label) ? activeBackgroundColorComputed : convert500ThemeToColor(item.backgroundColor ?? 'white')}`"
+        :style="`background-color: ${activeBackgroundColorComputed && ((value && value === item.value) || value === item.label) ? activeBackgroundColorComputed : convertThemeToColor(item.backgroundColor ?? 'white', item.darknessBackgroundColor ?? 500)}`"
         :class="[
           'background',
           {
@@ -92,7 +97,7 @@ const buttonHeight = computed(() => {
       ></span>
       <span
         v-if="!item.isLabelHidden"
-        :style="`color: ${value === item.value || value === item.label ? item.activeColor : convert500ThemeToColor(item.color ?? 'black')}; font-size: ${textSize}`"
+        :style="`color: ${(item.value && value === item.value) || value === item.label ? convertThemeToColor(item.activeColor ?? 'black', item.darknessActiveColor ?? 500) : convertThemeToColor(item.color ?? 'black', item.darknessColor ?? 500)}; font-size: ${textSize}`"
         :class="[
           'text',
           {
@@ -102,7 +107,8 @@ const buttonHeight = computed(() => {
         ]"
         >{{ item.label ?? index }}</span
       >
-      <div
+      <span
+        v-if="$slots[`${index + 1}Icon`]"
         :class="[
           'icon',
           {
@@ -111,7 +117,7 @@ const buttonHeight = computed(() => {
         ]"
       >
         <slot :name="`${index + 1}Icon`" />
-      </div>
+      </span>
     </button>
   </div>
 </template>
diff --git a/src/stories/components/Slider/Slider.stories.ts b/src/stories/components/Slider/Slider.stories.ts
index d465efa..98211f2 100644
--- a/src/stories/components/Slider/Slider.stories.ts
+++ b/src/stories/components/Slider/Slider.stories.ts
@@ -22,13 +22,18 @@ const meta: Meta = {
     size: { control: 'select', options: ['small', 'medium', 'large', 'huge'] },
     orientation: { control: 'select', options: ['horizontal', 'vertical'] },
     isSmooth: { control: 'boolean' },
+    darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
+    darknessBackgroundColor: {
+      control: 'select',
+      options: [100, 200, 300, 400, 500, 600, 700, 800, 900],
+    },
     theme: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -46,9 +51,9 @@ const meta: Meta = {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
diff --git a/src/stories/components/Slider/Slider.vue b/src/stories/components/Slider/Slider.vue
index 47b6fcb..5d57dc4 100644
--- a/src/stories/components/Slider/Slider.vue
+++ b/src/stories/components/Slider/Slider.vue
@@ -1,13 +1,15 @@
 <script setup lang="ts">
 import { computed, ref, watch } from 'vue';
-import { convert500ThemeToColor } from '@helpers/colors';
 import type { ISliderProps } from '@interfaces/componentsProps';
+import { convertThemeToColor } from '@helpers/common';
 
 const props = withDefaults(defineProps<ISliderProps>(), {
   width: '100',
   size: 'medium',
   theme: 'sky',
   backgroundColor: 'black',
+  darknessTheme: 500,
+  darknessBackgroundColor: 500,
 });
 const value = defineModel('value');
 const optionValue = ref(
@@ -57,8 +59,10 @@ const widthHalf = computed(() => `${Math.floor(+props.width / 2)}px`);
 const sliderHeight = computed(() => `${Math.floor(+sliderButtonSize.value.slice(0, -2) / 2.5)}px`);
 const sliderBorderRadius = computed(() => (props.isSmooth ? sliderHeight.value : '0%'));
 const sliderButtonBorderRadius = computed(() => (props.isSmooth ? '50%' : '0%'));
-const themeColor = computed(() => convert500ThemeToColor(props.theme));
-const themeBackground = computed(() => convert500ThemeToColor(props.backgroundColor));
+const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
+const themeBackground = computed(() =>
+  convertThemeToColor(props.backgroundColor, props.darknessBackgroundColor),
+);
 const marksListPadding = computed(
   () => `${Math.floor(+sliderButtonSize.value.slice(0, -2) / 2)}px`,
 );
@@ -86,9 +90,9 @@ const marksListPadding = computed(
       <ul class="marksList" :style="`width: ${width ?? 200}px`">
         <li
           v-for="option of options"
-          :key="option.label"
+          :key="String(option.label)"
           class="mark"
-          :style="`color: ${convert500ThemeToColor(option?.color) ?? 'white'}; font-size: ${optionsFontSize}`"
+          :style="`color: ${convertThemeToColor(option.color ?? 'black', option.darknessColor ?? 500) ?? 'white'}; font-size: ${optionsFontSize}`"
         >
           {{ option.label }}
         </li>
diff --git a/src/stories/components/ToggleSwitch/ToggleSwitch.stories.ts b/src/stories/components/ToggleSwitch/ToggleSwitch.stories.ts
index c003e86..0fe5c11 100644
--- a/src/stories/components/ToggleSwitch/ToggleSwitch.stories.ts
+++ b/src/stories/components/ToggleSwitch/ToggleSwitch.stories.ts
@@ -20,9 +20,9 @@ const meta: Meta = {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -40,9 +40,9 @@ const meta: Meta = {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -56,7 +56,11 @@ const meta: Meta = {
         'black',
       ],
     },
-    darkNegative: { control: 'boolean' },
+    darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
+    darknessNegativeTheme: {
+      control: 'select',
+      options: [100, 200, 300, 400, 500, 600, 700, 800, 900],
+    },
     disabled: { control: 'boolean' },
   },
   args: {},
@@ -68,14 +72,12 @@ type Story = StoryObj<typeof meta>;
 
 export const Primary: Story = {
   args: {
-    darkNegative: true,
     active: false,
   },
 };
 
 export const SmallLight: Story = {
   args: {
-    darkNegative: false,
     negativeTheme: 'yellow',
     theme: 'red',
     size: 'small',
@@ -84,7 +86,6 @@ export const SmallLight: Story = {
 
 export const Large: Story = {
   args: {
-    darkNegative: true,
     negativeTheme: 'purple',
     theme: 'green',
     size: 'large',
@@ -93,7 +94,6 @@ export const Large: Story = {
 
 export const Huge: Story = {
   args: {
-    darkNegative: true,
     negativeTheme: 'blue',
     theme: 'orange',
     size: 'huge',
diff --git a/src/stories/components/ToggleSwitch/ToggleSwitch.vue b/src/stories/components/ToggleSwitch/ToggleSwitch.vue
index 503feb5..7be5d7a 100644
--- a/src/stories/components/ToggleSwitch/ToggleSwitch.vue
+++ b/src/stories/components/ToggleSwitch/ToggleSwitch.vue
@@ -1,21 +1,20 @@
 <script setup lang="ts">
 import { computed } from 'vue';
-import { convert500ThemeToColor, convert800ThemeToColor } from '@helpers/colors';
 import type { ITSProps } from '@interfaces/componentsProps';
+import { convertThemeToColor } from '@helpers/common';
 
 const props = withDefaults(defineProps<ITSProps>(), {
   size: 'medium',
   theme: 'sky',
   negativeTheme: 'black',
-  darkNegative: true,
+  darknessTheme: 500,
+  darknessNegativeTheme: 500,
 });
 const active = defineModel<boolean>('active');
 
-const themeColor = computed(() => convert500ThemeToColor(props.theme));
+const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
 const inactiveColor = computed(() =>
-  props.darkNegative
-    ? convert800ThemeToColor(props.negativeTheme)
-    : convert500ThemeToColor(props.negativeTheme),
+  convertThemeToColor(props.negativeTheme, props.darknessNegativeTheme),
 );
 const sizes = computed(() => {
   if (!props?.size) {
diff --git a/src/stories/components/TreeList/TreeItems.vue b/src/stories/components/TreeList/TreeItems.vue
index 2dd704c..bbd871b 100644
--- a/src/stories/components/TreeList/TreeItems.vue
+++ b/src/stories/components/TreeList/TreeItems.vue
@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import { iconsSet } from '@/common/constants/icons';
 import TriangleIcon from '@stories/icons/Mono/TriangleIcon.vue';
-import { convert500ThemeToColor } from '@helpers/colors';
 import type { ITIProps } from '@interfaces/componentsProps';
+import { convertThemeToColor } from '@helpers/common';
 
 defineProps<ITIProps>();
 const emit = defineEmits(['toggleIsOpen', 'onClick']);
@@ -44,7 +44,9 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']);
               },
             ]"
             :color="
-              item.color && item.isTriangleToColor ? convert500ThemeToColor(item.color) : textColor
+              item.color && item.isTriangleToColor
+                ? convertThemeToColor(item.color, item.darknessColor ?? 500)
+                : textColor
             "
             size="17"
           />
@@ -59,7 +61,7 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']);
                 isDarkerOnHover: item.link,
               },
             ]"
-            :style="`color: ${item.color ? convert500ThemeToColor(item.color) : textColor}`"
+            :style="`color: ${item.color ? convertThemeToColor(item.color, item.darknessColor ?? 500) : textColor}`"
             @click="
               () => {
                 item.isLinkClicked = true;
@@ -72,14 +74,14 @@ const emit = defineEmits(['toggleIsOpen', 'onClick']);
             ><component
               :is="iconsSet[item.iconBefore]"
               v-if="item.iconBefore"
-              :color="convert500ThemeToColor(item.iconColor)"
+              :color="convertThemeToColor(item.iconColor ?? 'black', item.darknessIconColor ?? 500)"
               style="min-width: 17px"
               size="17" />
             <span>{{ item.label }}</span
             ><component
               :is="iconsSet[item.iconAfter]"
               v-if="item.iconAfter"
-              :color="convert500ThemeToColor(item.iconColor)"
+              :color="convertThemeToColor(item.iconColor ?? 'black', item.darknessIconColor ?? 500)"
               style="min-width: 17px"
               size="17"
           /></a>
diff --git a/src/stories/components/TreeList/TreeList.stories.ts b/src/stories/components/TreeList/TreeList.stories.ts
index 9be416a..8c2165e 100644
--- a/src/stories/components/TreeList/TreeList.stories.ts
+++ b/src/stories/components/TreeList/TreeList.stories.ts
@@ -18,13 +18,14 @@ const meta: Meta = {
     items: { control: 'object' },
     maxWidth: { control: 'number' },
     expand: { control: 'boolean' },
+    darknessTheme: { control: 'select', options: [100, 200, 300, 400, 500, 600, 700, 800, 900] },
     theme: {
       control: 'select',
       options: [
         'white',
-        'slate',
         'blue',
         'sky',
+        'cyan',
         'teal',
         'green',
         'yellow',
@@ -124,6 +125,8 @@ export const Full: Story = {
                 color: 'red',
                 iconAfter: 'DiceIcon',
                 iconColor: 'red',
+                darknessColor: 400,
+                darknessIconColor: 400,
                 children: [
                   {
                     label: '1-1-1-1',
@@ -160,5 +163,6 @@ export const Full: Story = {
 
     expand: true,
     theme: 'black',
+    darknessTheme: 800,
   },
 };
diff --git a/src/stories/components/TreeList/TreeList.vue b/src/stories/components/TreeList/TreeList.vue
index 061fe64..d4b1f5c 100644
--- a/src/stories/components/TreeList/TreeList.vue
+++ b/src/stories/components/TreeList/TreeList.vue
@@ -1,9 +1,9 @@
 <script setup lang="ts">
 import { computed, ref, watch } from 'vue';
 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';
+import { convertThemeToColor } from '@helpers/common';
 
 interface IStateItem {
   isOpen: boolean;
@@ -13,14 +13,15 @@ interface IStateItem {
 const props = withDefaults(defineProps<ITLProps>(), {
   theme: 'white',
   maxWidth: 300,
+  darknessTheme: 500,
 });
 const emit = defineEmits(['onClick']);
 const items = computed(() => props.items);
-const themeColor = computed(() => convert500ThemeToColor(props.theme));
+const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
 const textColor = computed(() => {
-  if (!props.theme) return 'black';
-  if (props.theme === 'white') return 'black';
-  return 'white';
+  if (props.theme === 'white' || (props.darknessTheme <= 600 && props.theme !== 'black'))
+    return '#000000';
+  return '#ffffff';
 });
 
 const state = ref<IStateItem[]>([]);
-- 
GitLab