Собираем NavMenu, которое будет интерактивным.

Осталось всего несколько до конца этого урока. Мы рассмотрели компоненты, расположенные в верхней части панели навигации, и теперь мы можем открыть меню, наведя курсор, который передается компоненту NavBar.

Но какое меню?

Да, мы к этому вернемся.

Nav (navOpen, data)  
├── Navbar (navOpen, data)  
│   ├── NavLogo (data.logo)  
|	├── NavLinks (navOpen, data.links as link)  
|	├── **NavActions**
|	|	├── NavSearch  
|	|	├── NavUser 
|	|	├── CTA 
|  
├── NavMenu (navOpen, data.links as link)  
|	├── NavLink (link.links)  
|	├── VariableContent  
|  
├── MobileNavbar (navOpen, data.links)  
|	├── NavLogo 
|   ├── **NavActions**
|	├── Hamburger (navOpen)  
|	├── AccordionLinks (data.links)

Переменные передаются по этому дереву, пока не достигнут интерактивных элементов. Взаимодействия изменяют значения переменных, а переменные, доступные из панели навигации, распространяются на их дочерние компоненты.

Теперь, чтобы продолжить, мы собираемся сделать NavMenu.

NavMenu.svelte

NavMenu.svelte — это компонент меню навигации, который можно использовать для создания динамических интерактивных меню навигации. Он использует три других компонента Svelte: Button, NavMenuLink и VariableContent, которые мы создадим позже.

Шаг 1: Импорт зависимостей

В верхней части NavMenu.svelte вам нужно будет импортировать остальные три компонента. Это делается с помощью ключевого слова import, за которым следует относительный путь компонента, который вы хотите импортировать. Например:

import Button from "./button.svelte"
import NavMenuLink from "./NavMenuLink.svelte"
import VariableContent from "./VariableContent.svelte"

Шаг 2: Инициализируйте экспортированные переменные

NavMenu.svelte экспортирует три переменные: data, selectedView и navOpen. Эти переменные должны быть инициализированы желаемыми значениями. Это делается с помощью ключевого слова export let, за которым следует имя переменной. Например:

export let data;
export let selectedView;
export let navOpen;

Шаг 3: Добавьте HTML меню навигации

После инициализации переменных вы можете добавить HTML-код, необходимый для создания меню навигации. Этот HTML должен быть заключен в оператор if, который будет проверять значение переменной navOpen. Если эта переменная true, то будет отображаться меню навигации.

Шаг 4: Добавьте стили CSS

Наконец, вам нужно будет добавить все необходимые стили CSS к div элементам. Это можно сделать, добавив атрибут style к каждому элементу. Мы сдвинем вид вправо на 90 пикселей с помощью переменной selectedView.

<div class="absolute hidden lg:block 
	  border border-1 border-gray-300 border-t-0
          rounded-b-lg
          top-[89px] bg-white" style={`left:${200 + (selectedView * 90)}px`}>

NavLink.svelte

NavLink.svelte — это компонент навигационной ссылки, который можно использовать для создания динамических навигационных меню. Он использует еще один компонент Svelte: NavLink.

Шаг 1: Импорт зависимостей

Для этого мы собираемся повторно использовать компонент NavLink, поэтому нам не нужно изобретать велосипед.

import NavLink from "./NavLink.svelte"

Шаг 2: Инициализируйте экспортированные переменные

Теперь настроим переменные, которые будут переданы в основной компонент Nav.

export let data = {};
export let navOpen = false;
export let selectedView = 0;

Шаг 3. Добавьте HTML-код навигационной ссылки.

После инициализации переменных вы можете добавить HTML-код, необходимый для создания навигационной ссылки. Этот HTML должен включать элемент div с классами flex, items-center и grow. Внутри этого элемента вы должны использовать цикл #each для перебора массива data.links и рендеринга компонента NavLink для каждой ссылки. Вы также должны добавить обработчик события on:mouseenter к элементу div, который будет вызывать функцию makeHandleEnter и передавать индекс ссылки.

<div class="flex items-center grow">
	{#each data.links as lnk,index}
		<div on:mouseenter={makeHandleEnter(index)}>
			<NavLink href={"#"} name={lnk.title} />
		</div>
	{/each}
</div>

Шаг 4: Добавьте функцию makeHandleEnter()

Функция makeHandleEnter() будет использоваться для установки значения переменной selectedView и открытия меню навигации. Это можно сделать, добавив функцию в тег <script>. Функция должна принять параметр idx и установить для переменной selectedView значение idx, а для переменной navOpen установить значение true. Например:

function makeHandleEnter(idx) {
	return function handleEnter(){
		selectedView = idx;
		navOpen = true;
	}
}

И результирующий код должен выглядеть так:

<script>

import NavLink from "./NavLink.svelte"
export let data = {};
export let navOpen = false;
export let selectedView = 0;
function makeHandleEnter(idx) {
 return function handleEnter(){
  selectedView = idx;
  navOpen = true;
 }
}

</script>

<div class="flex items-center grow">
 {#each data.links as lnk,index}
  <div on:mouseenter={makeHandleEnter(index)}>
   <NavLink href={"#"} name={lnk.title} />
  </div>
 {/each}
</div>

Сделав это, мы сможем создать компонент VariableContent, который будет содержать несколько разных макетов, что позволит нам изменить то, что отображается, просто изменив переменную.

VariableContent.svelte

VariableContent.svelte — это компонент Svelte, который можно использовать для отображения различных типов контента на основе заданного объекта данных.

Шаг 1: Инициализируйте переменную данных

В верхней части VariableContent.svelte вам нужно будет инициализировать экспортированную переменную data. Это делается с помощью ключевого слова export let, за которым следует имя переменной. Например:

export let data;

Шаг 2: Добавьте контент HTML

После инициализации переменной data вы можете добавить HTML-код, необходимый для отображения различных типов контента. Это должно быть сделано с помощью операторов if, которые будут проверять свойство data.type и отображать соответствующий контент.

Например, если свойство data.type равно card_item, следует отобразить следующий HTML-код:

<div class="min-w-[250px] max-w-[350px] p-8 bg-gray-100 flex flex-col gap-4">
	{#if data.img}
		<img src={data.img}>
	{/if}
	<div class="text-large font-bold">
		{data.name}
	</div>
	<div class="font-light text-gray-500">
		{data.text}
	</div>
	<div class="pt-4">
		<a class="border border-blue-600 text-blue-600 p-3 px-5 rounded-md" href={data.link}>{data.link_text}</a>
	</div>
</div>

Точно так же, если свойство data.type равно preview_item, то должен быть отображен следующий HTML:

<a href={data.link} class="p-4">
	<div style={`background-image: url(${data.img})`} class="bg-center rounded-md  bg-cover bg-no-repeat max-w-[300px] min-h-[400px] flex items-end ">
		<div class="p-4 pt-8 bg-gradient-to-t from-black rounded-md">
			<div class="text-white text-lg font-bold">
				{data.name}
			</div>
			<div class="text-gray-300 text-bold">
				{data.text}
			</div>
		</div>
	</div>
</a>

Шаг 3: Добавьте стили CSS

Наконец, вам нужно будет добавить все необходимые стили CSS к элементам HTML. Это можно сделать, добавив атрибут style к каждому элементу. Например:

<div style={`background-image: url(${data.img})`} class="bg-center rounded-md  bg-cover bg-no-repeat max-w-[300px] min-h-[400px] flex items-end ">

На этом этот раздел учебника заканчивается. Затем мы вернемся, чтобы добавить компонент NavUser, где мы узнаем о модуле writable, который поможет нам хранить данные во внешнем интерфейсе и свободно управлять состоянием «logged_in».