From 5d51ed45ac9587243fad624572e40bbc1a8758f3 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: Tue, 17 Dec 2024 13:24:50 +0500
Subject: [PATCH] feat: finished - MenuDial (but only 4 direction options:
 'up', 'right', 'down' and 'left')

---
 .../components/MenuDial/MenuDial.stories.ts   | 10 ++--
 src/stories/components/MenuDial/MenuDial.vue  | 60 ++++++++++---------
 2 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/src/stories/components/MenuDial/MenuDial.stories.ts b/src/stories/components/MenuDial/MenuDial.stories.ts
index d80539d..a91196a 100644
--- a/src/stories/components/MenuDial/MenuDial.stories.ts
+++ b/src/stories/components/MenuDial/MenuDial.stories.ts
@@ -38,10 +38,7 @@ const meta: Meta = {
       ],
     },
   },
-  args: {
-    // primary: false,
-    // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
-  },
+  args: {},
 } satisfies Meta<typeof MenuDial>;
 
 export default meta;
@@ -67,12 +64,15 @@ export const Full: Story = {
   args: {
     items: [
       {
-        label: 'First',
+        label: 'font-family link',
         theme: 'green',
+        link: 'https://developer.mozilla.org/en-US/docs/Web/CSS/font-family',
+        linkBlank: true,
       },
       {
         label: 'Second',
         theme: 'green',
+        textStyle: 'italic',
       },
     ],
 
diff --git a/src/stories/components/MenuDial/MenuDial.vue b/src/stories/components/MenuDial/MenuDial.vue
index 632da61..5b54129 100644
--- a/src/stories/components/MenuDial/MenuDial.vue
+++ b/src/stories/components/MenuDial/MenuDial.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { computed, watch } from 'vue';
+import { computed } from 'vue';
 import type { IMDProps } from '@interfaces/componentsProps';
 import { convert500ThemeToColor } from '@helpers/colors';
 import PlusIcon from '@stories/icons/Mono/PlusIcon.vue';
@@ -13,7 +13,6 @@ const active = defineModel('active');
 
 const themeColor = computed(() => convert500ThemeToColor(props.theme));
 const textColor = computed(() => {
-  if (!props.theme) return '#000000';
   if (props.theme === 'white') return '#000000';
   return '#ffffff';
 });
@@ -21,8 +20,6 @@ const elementsSize = computed(() => {
   switch (props.size) {
     case 'small':
       return 30;
-    case 'medium':
-      return 40;
     case 'large':
       return 55;
     case 'huge':
@@ -32,29 +29,32 @@ const elementsSize = computed(() => {
 });
 const menuListStyles = computed(() => {
   switch (props.direction) {
-    case 'right':
-      return `transform: translateY(-${elementsSize.value / 2}px) translateX(${active.value ? elementsSize.value + 10 : 0}px)`;
     case 'left':
-      return `flex-direction: row-reverse; transform: translateY(-${elementsSize.value / 2}px) ${active.value ? `translateX(calc(-100% - 10px))` : ''}`;
-    case 'top':
-      return `transform: translateY(-${active.value ? (0.5 + props.items.length) * elementsSize.value + 10 : elementsSize.value / 2}px)`;
-    case 'bottom':
-      return `transform: translateY(${active.value ? 20 : 0}px)`;
-  }
-  return `transform: translateY(-${elementsSize.value / 2}px) translateX(${active.value ? elementsSize.value + 10 : 0}px)`;
-});
-const onClick = () => {
-  active.value = false;
-};
-watch(active, () => {
-  if (active.value) {
-    setTimeout(() => {
-      document.addEventListener('click', onClick);
-    }, 0);
-  } else {
-    document.removeEventListener('click', onClick);
+      return `flex-direction: row-reverse; transform: translateY(-${elementsSize.value / 2}px) ${active.value ? `translateX(calc(-100% - 10px))` : 'translateX(calc(-100% + 60px))'}`;
+    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 `transform: translateY(-${elementsSize.value / 2}px) translateX(${active.value ? elementsSize.value + 10 : -20}px)`;
 });
+// const circleStylesItems = computed(() => {
+//   if (props.direction !== 'circle') {
+//     return '';
+//   }
+//   const styles = [];
+//   let deg = 0;
+//   const itemsCount = props.items.length;
+//   const degToItem = Math.round(360 / itemsCount);
+//   for (let i = 0; i < itemsCount; i++) {
+//     styles.push(`transform: rotate(${deg}deg) rotate(${-deg}deg)`);
+//     deg += degToItem;
+//   }
+//   console.log(styles);
+//   return styles;
+// });
+const openLink = (url: string, isBlank: boolean | undefined) =>
+  window.open(url, isBlank ? '_blank' : '_self');
 </script>
 
 <template>
@@ -81,9 +81,14 @@ watch(active, () => {
         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'}`"
+        color: ${!item.theme || item.theme === 'white' ? 'black' : 'white'}; border-color: ${!item.theme || item.theme === 'white' ? 'black' : 'white'};`"
         class="menuElement"
-        @click.prevent="() => (item.onClick ? item.onClick() : false)"
+        @click="
+          () => {
+            if (item.link) openLink(item.link, item.linkBlank);
+            if (item.onClick) item.onClick();
+          }
+        "
       >
         <slot :name="`${index + 1}IconBefore`" />
         <p
@@ -133,9 +138,6 @@ watch(active, () => {
   opacity: 0;
   transition: 0.2s ease-in-out;
 }
-.menuListColumn {
-  flex-direction: column;
-}
 .menuListOpened {
   pointer-events: auto;
   opacity: 1;
-- 
GitLab