Вынес термины в выпадающее меню

This commit is contained in:
Ilia Miheev
2026-06-02 22:29:49 +03:00
parent 817ccd3b23
commit 9db8220fdb
4 changed files with 215 additions and 53 deletions
+138 -24
View File
@@ -13,6 +13,7 @@
"@vueuse/core": "^14.2.1",
"copy-to-clipboard": "^3.3.3",
"electron-squirrel-startup": "^1.0.1",
"element-plus": "^2.14.1",
"izitoast": "^1.4.0",
"prismjs": "^1.30.0",
"vue": "^3.5.28",
@@ -100,6 +101,15 @@
"vue": "^3.0.11"
}
},
"node_modules/@ctrl/tinycolor": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz",
"integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==",
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/@electron-forge/cli": {
"version": "7.11.1",
"resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.11.1.tgz",
@@ -1032,6 +1042,15 @@
"node": ">=14.14"
}
},
"node_modules/@element-plus/icons-vue": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz",
"integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==",
"license": "MIT",
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/@emotion/hash": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
@@ -1430,6 +1449,31 @@
"node": ">=12"
}
},
"node_modules/@floating-ui/core": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
"integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.11"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.7.6",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
"integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.7.5",
"@floating-ui/utils": "^0.2.11"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
"integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
"license": "MIT"
},
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
@@ -2065,6 +2109,17 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/@popperjs/core": {
"name": "@sxzz/popperjs-es",
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.8.tgz",
"integrity": "sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz",
@@ -2539,15 +2594,14 @@
"version": "4.17.24",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz",
"integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/lodash": "*"
}
@@ -2737,14 +2791,14 @@
"license": "MIT"
},
"node_modules/@vueuse/core": {
"version": "14.2.1",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-14.2.1.tgz",
"integrity": "sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ==",
"version": "14.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-14.3.0.tgz",
"integrity": "sha512-aHfz47g0ZhMtTVHmIzMVpJy8ePhhOy68GY5bv110+5DVtZ+W7BsOx+m61UNQqfrWyPztIHIanWa3E2tib3NFIw==",
"license": "MIT",
"dependencies": {
"@types/web-bluetooth": "^0.0.21",
"@vueuse/metadata": "14.2.1",
"@vueuse/shared": "14.2.1"
"@vueuse/metadata": "14.3.0",
"@vueuse/shared": "14.3.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
@@ -2754,18 +2808,18 @@
}
},
"node_modules/@vueuse/metadata": {
"version": "14.2.1",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-14.2.1.tgz",
"integrity": "sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw==",
"version": "14.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-14.3.0.tgz",
"integrity": "sha512-BwxmbAzwAVF50+MW57GXOUEV61nFBGnlBvrTqj49PqWJu3uw7hdu72ztXeZ33RdZtDY6kO+bfCAE1PCn88Tktw==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "14.2.1",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-14.2.1.tgz",
"integrity": "sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw==",
"version": "14.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-14.3.0.tgz",
"integrity": "sha512-bZpge9eSXwa4ToSiqJ7j6KRwhAsneMFoSz3LMWKQDkqimm3D/tbFlrklrs/IOqC8tEcYmXQZJ6N0UrjhBirVCg==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
@@ -3131,7 +3185,6 @@
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
"dev": true,
"license": "MIT"
},
"node_modules/at-least-node": {
@@ -3822,6 +3875,12 @@
"date-fns": "^3.0.0 || ^4.0.0"
}
},
"node_modules/dayjs": {
"version": "1.11.21",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.21.tgz",
"integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==",
"license": "MIT"
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
@@ -4605,6 +4664,32 @@
"node": ">= 4.0.0"
}
},
"node_modules/element-plus": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.14.1.tgz",
"integrity": "sha512-UFnm1+BckNi+azkKJ7L32q1uXs9ekr99Z9pWTQPeDR05jqEWUwQq51ro4kZMVrANbjknX3Z7ukCZwTi2T6Tr9A==",
"license": "MIT",
"dependencies": {
"@ctrl/tinycolor": "^4.2.0",
"@element-plus/icons-vue": "^2.3.2",
"@floating-ui/dom": "^1.7.6",
"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.8",
"@types/lodash": "^4.17.24",
"@types/lodash-es": "^4.17.12",
"@vueuse/core": "14.3.0",
"async-validator": "^4.2.5",
"dayjs": "^1.11.20",
"lodash": "^4.18.1",
"lodash-es": "^4.18.1",
"lodash-unified": "^1.0.3",
"memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.2.0",
"vue-component-type-helpers": "^3.3.1"
},
"peerDependencies": {
"vue": "^3.3.7"
}
},
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
@@ -5968,18 +6053,29 @@
}
},
"node_modules/lodash": {
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
"dev": true,
"license": "MIT"
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"license": "MIT",
"peer": true
},
"node_modules/lodash-es": {
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
"integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==",
"dev": true,
"license": "MIT"
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
"integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
"license": "MIT",
"peer": true
},
"node_modules/lodash-unified": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
"integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
"license": "MIT",
"peerDependencies": {
"@types/lodash-es": "*",
"lodash": "*",
"lodash-es": "*"
}
},
"node_modules/lodash.get": {
"version": "4.4.2",
@@ -6125,6 +6221,12 @@
"node": ">=6"
}
},
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
"license": "MIT"
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -6527,6 +6629,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/normalize-wheel-es": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
"integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==",
"license": "BSD-3-Clause"
},
"node_modules/npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@@ -8315,6 +8423,12 @@
}
}
},
"node_modules/vue-component-type-helpers": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-3.3.3.tgz",
"integrity": "sha512-x4nsFpy5Pe8fqPzp/5vkTPeTTDBpAx4WVtV47Ejt0+2FQrq4pRRsJs7JmYRqMFzTu/LW+pCWEjQ3YVCkPV7f9g==",
"license": "MIT"
},
"node_modules/vue-router": {
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz",
+1
View File
@@ -35,6 +35,7 @@
"@vueuse/core": "^14.2.1",
"copy-to-clipboard": "^3.3.3",
"electron-squirrel-startup": "^1.0.1",
"element-plus": "^2.14.1",
"izitoast": "^1.4.0",
"prismjs": "^1.30.0",
"vue": "^3.5.28",
+70 -29
View File
@@ -1,34 +1,49 @@
<template>
<div class="navigation-wrapper">
<!-- Кнопка Бургер -->
<button class="burger-btn" @click="toggleMenu" :class="{ 'is-active': isOpen }" aria-label="Menu">
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
</button>
<!-- Затемнение заднего фона (Overlay) -->
<transition name="fade">
<div v-if="isOpen" class="overlay" @click="closeMenu"></div>
</transition>
<!-- Выпадающая панель -->
<transition name="slide">
<aside v-if="isOpen" class="side-panel">
<aside v-show="isOpen" class="side-panel scroll-strip">
<div class="menu-header">
<h1>SkyVue</h1>
</div>
<nav class="menu-content">
<custom-button
@click="openInfoCard(item)"
v-for="item in informationForDirectory"
>
{{ item.title }}
</custom-button>
</nav>
<el-menu
class="menu-content"
background-color="transparent"
text-color="#ffffff"
active-text-color="#23aae3"
>
<el-sub-menu index="terms">
<template #title>
<span class="menu-content__group-title">Термины</span>
</template>
<el-menu-item
v-for="(item, index) in informationForDirectory"
:key="item.title"
:index="`term-${index}`"
class="terms-menu-item"
@click="openInfoCard(item)"
>
<ListCard
:title="item.title"
:subtitle="getSubtitle(item.body)"
:active="isModalVisible && infoCard.title === item.title"
/>
</el-menu-item>
</el-sub-menu>
</el-menu>
</aside>
</transition>
<MyDialog isSuccess v-model:show="isModalVisible" @close="handleOkBtn">
<template #header>
<strong>{{ infoCard.title }}</strong>
@@ -39,8 +54,7 @@
<template #footer>
<div class="navigation-wrapper__footer">
<custom-button :to="infoCard.hrefToCourse" title="Посмотреть на Stepik">Курс</custom-button>
<custom-button :to="infoCard.hrefToDoc" title="Посмотреть в официальной документации">Документация
</custom-button>
<custom-button :to="infoCard.hrefToDoc" title="Посмотреть в официальной документации">Документация</custom-button>
<custom-button @click="handleOkBtn">ОК</custom-button>
</div>
</template>
@@ -49,16 +63,22 @@
</template>
<script setup>
import {ref} from 'vue';
import { ref } from 'vue';
import MyDialog from "@/components/MyDialog.vue";
import CustomButton from '@/components/UI/CustomButton.vue'
import ListCard from '@/components/UI/ListCard.vue'
import informationForDirectory from "../data/informationForDirectory";
import {useEventListener} from "@vueuse/core";
import { useEventListener } from "@vueuse/core";
const isOpen = ref(false);
const isModalVisible = ref(false);
const infoCard = ref({})
function getSubtitle(body) {
if (!body) return ''
return body.length > 72 ? `${body.slice(0, 72)}` : body
}
function handleOkBtn() {
isModalVisible.value = false
isOpen.value = true
@@ -86,8 +106,7 @@ const handleKeydown = (event) => {
};
useEventListener("keydown", handleKeydown);
// Экспортируем методы, если захотим управлять меню извне
defineExpose({open: () => (isOpen.value = true), close: closeMenu});
defineExpose({ open: () => (isOpen.value = true), close: closeMenu });
</script>
<style scoped>
@@ -112,20 +131,46 @@ h1 {
}
.menu-content {
display: flex;
flex-direction: column;
gap: 10px;
border-right: none;
}
.menu-content__group-title {
font-size: 16px;
font-weight: 600;
}
.menu-content :deep(.el-sub-menu__title) {
border-radius: 10px;
}
.menu-content :deep(.el-sub-menu__title:hover) {
background-color: rgba(255, 255, 255, 0.1);
}
.terms-menu-item {
height: auto;
line-height: normal;
padding: 0;
margin-bottom: 4px;
white-space: normal;
}
.terms-menu-item :deep(.list-card) {
margin: 0;
width: 100%;
}
.terms-menu-item.is-active {
background-color: transparent !important;
}
.line {
width: 100%;
height: 4px;
background-color: #383838;
/* Ярко-красный цвет для теста */
transition: all 0.3s ease;
}
/* Анимация бургера в крестик */
.is-active .line:nth-child(1) {
transform: translateY(6px) rotate(45deg);
}
@@ -138,23 +183,20 @@ h1 {
transform: translateY(-6px) rotate(-45deg);
}
/* Боковая панель */
.side-panel {
position: fixed;
top: 0;
left: 0;
width: 25%;
min-width: 280px;
height: 100%;
background-image: radial-gradient(#23aae3e2, #222222);
color: white;
z-index: 2;
padding: 0 20px 20px;
overflow-y: scroll;
overflow: auto;
padding: 0 12px 20px;
border-right: white 2px solid;
}
/* Затемнение фона */
.overlay {
position: fixed;
top: 0;
@@ -177,7 +219,6 @@ main {
width: 100%;
}
/* Анимации появления */
.slide-enter-active,
.slide-leave-active {
transition: transform 0.39s ease;
+6
View File
@@ -1,3 +1,8 @@
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'dayjs/locale/ru'
import ru from 'element-plus/es/locale/lang/ru'
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
@@ -9,5 +14,6 @@ import ContextMenu from '@imengyu/vue3-context-menu'
const app = createApp(App)
app.use(router)
app.use(ElementPlus, { locale: ru })
app.use(ContextMenu)
app.mount('#app')