# 🎨 Руководство по Material Web Components 3 **Только Material компоненты! Никаких собственных компонентов!** --- ## 📦 Установка и настройка ```bash npm install @material/web ``` --- ## 🔧 Настройка TypeScript Создать файл `types/material-web.d.ts`: ```typescript // Декларации для Material Web Components declare namespace JSX { interface IntrinsicElements { // Buttons 'md-filled-button': any; 'md-outlined-button': any; 'md-text-button': any; 'md-elevated-button': any; 'md-tonal-button': any; 'md-filled-tonal-button': any; // Text Fields 'md-filled-text-field': any; 'md-outlined-text-field': any; // Cards 'md-filled-card': any; 'md-elevated-card': any; 'md-outlined-card': any; // Lists 'md-list': any; 'md-list-item': any; // Navigation 'md-navigation-bar': any; 'md-navigation-tab': any; 'md-navigation-drawer': any; 'md-navigation-drawer-modal': any; // Dialogs & Sheets 'md-dialog': any; // Chips 'md-chip-set': any; 'md-assist-chip': any; 'md-filter-chip': any; 'md-input-chip': any; 'md-suggestion-chip': any; // Icons 'md-icon': any; 'md-icon-button': any; 'md-filled-icon-button': any; 'md-tonal-icon-button': any; 'md-outlined-icon-button': any; // Form Controls 'md-checkbox': any; 'md-radio': any; 'md-switch': any; 'md-slider': any; // Select 'md-filled-select': any; 'md-outlined-select': any; 'md-select-option': any; // Menus 'md-menu': any; 'md-menu-item': any; 'md-sub-menu': any; // Progress 'md-circular-progress': any; 'md-linear-progress': any; // FAB 'md-fab': any; 'md-branded-fab': any; // Badges 'md-badge': any; // Divider 'md-divider': any; // Tabs 'md-tabs': any; 'md-primary-tab': any; 'md-secondary-tab': any; } } ``` --- ## 📚 Импорт компонентов Создать файл `lib/material-components.ts`: ```typescript // Buttons import '@material/web/button/filled-button.js'; import '@material/web/button/outlined-button.js'; import '@material/web/button/text-button.js'; import '@material/web/button/elevated-button.js'; import '@material/web/button/tonal-button.js'; // Text Fields import '@material/web/textfield/filled-text-field.js'; import '@material/web/textfield/outlined-text-field.js'; // Cards import '@material/web/labs/card/filled-card.js'; import '@material/web/labs/card/elevated-card.js'; import '@material/web/labs/card/outlined-card.js'; // Lists import '@material/web/list/list.js'; import '@material/web/list/list-item.js'; // Navigation (из labs) import '@material/web/labs/navigationbar/navigation-bar.js'; import '@material/web/labs/navigationtab/navigation-tab.js'; import '@material/web/labs/navigationdrawer/navigation-drawer.js'; // Dialogs import '@material/web/dialog/dialog.js'; // Chips import '@material/web/chips/chip-set.js'; import '@material/web/chips/assist-chip.js'; import '@material/web/chips/filter-chip.js'; import '@material/web/chips/input-chip.js'; import '@material/web/chips/suggestion-chip.js'; // Icons import '@material/web/icon/icon.js'; import '@material/web/iconbutton/icon-button.js'; import '@material/web/iconbutton/filled-icon-button.js'; import '@material/web/iconbutton/tonal-icon-button.js'; import '@material/web/iconbutton/outlined-icon-button.js'; // Form Controls import '@material/web/checkbox/checkbox.js'; import '@material/web/radio/radio.js'; import '@material/web/switch/switch.js'; import '@material/web/slider/slider.js'; // Select import '@material/web/select/filled-select.js'; import '@material/web/select/outlined-select.js'; import '@material/web/select/select-option.js'; // Menus import '@material/web/menu/menu.js'; import '@material/web/menu/menu-item.js'; import '@material/web/menu/sub-menu.js'; // Progress import '@material/web/progress/circular-progress.js'; import '@material/web/progress/linear-progress.js'; // FAB import '@material/web/fab/fab.js'; import '@material/web/fab/branded-fab.js'; // Badges import '@material/web/labs/badge/badge.js'; // Divider import '@material/web/divider/divider.js'; // Tabs import '@material/web/tabs/tabs.js'; import '@material/web/tabs/primary-tab.js'; import '@material/web/tabs/secondary-tab.js'; ``` Импортировать в `app/layout.tsx`: ```typescript import '@/lib/material-components'; ``` --- ## 🎨 Material Design 3 Grid System Создать файл `styles/material-grid.css`: ```css /* Material Design 3 Layout Grid */ /* Breakpoints: - xs: 0-599px (Mobile) - sm: 600-839px (Tablet Portrait) - md: 840-1239px (Tablet Landscape / Small Desktop) - lg: 1240-1439px (Desktop) - xl: 1440px+ (Large Desktop) */ .md-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; padding: 0 16px; width: 100%; } /* Tablet Portrait (600-839px) */ @media (min-width: 600px) { .md-grid { grid-template-columns: repeat(8, 1fr); gap: 24px; padding: 0 24px; } } /* Tablet Landscape / Desktop (840-1239px) */ @media (min-width: 840px) { .md-grid { grid-template-columns: repeat(12, 1fr); gap: 24px; padding: 0 24px; } } /* Large Desktop (1240px+) */ @media (min-width: 1240px) { .md-grid { gap: 24px; padding: 0 24px; max-width: 1200px; margin: 0 auto; } } /* Column Span Classes */ /* Mobile (4 columns) */ .md-col-1 { grid-column: span 1; } .md-col-2 { grid-column: span 2; } .md-col-3 { grid-column: span 3; } .md-col-4 { grid-column: span 4; } /* Tablet (8 columns) */ @media (min-width: 600px) { .md-col-sm-1 { grid-column: span 1; } .md-col-sm-2 { grid-column: span 2; } .md-col-sm-4 { grid-column: span 4; } .md-col-sm-6 { grid-column: span 6; } .md-col-sm-8 { grid-column: span 8; } } /* Desktop (12 columns) */ @media (min-width: 840px) { .md-col-md-3 { grid-column: span 3; } .md-col-md-4 { grid-column: span 4; } .md-col-md-6 { grid-column: span 6; } .md-col-md-8 { grid-column: span 8; } .md-col-md-9 { grid-column: span 9; } .md-col-md-12 { grid-column: span 12; } } /* Flexbox альтернатива для простых случаев */ .md-flex { display: flex; gap: 16px; } .md-flex-col { display: flex; flex-direction: column; gap: 16px; } .md-flex-wrap { flex-wrap: wrap; } ``` **Использование:** ```tsx
Карточка 1
Карточка 2
``` --- ## 📱 Примеры использования компонентов ### 1. Форма входа ```tsx 'use client'; export default function LoginPage() { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); // Логика входа }; return (

Вход в систему

Войти
); } ``` ### 2. Дашборд с карточками ```tsx 'use client'; export default function DashboardPage() { return (
{/* Статистика */}
groups

24

Студентов

calendar_month

12

Занятий на неделе

payments

45000₽

Доход за месяц

); } ``` ### 3. Bottom Navigation Bar (iOS-style) ```tsx 'use client'; import { usePathname, useRouter } from 'next/navigation'; import { useEffect, useRef } from 'react'; export function BottomNavigationBar({ userRole }: { userRole: 'mentor' | 'client' | 'parent' }) { const pathname = usePathname(); const router = useRouter(); const navRef = useRef(null); useEffect(() => { const nav = navRef.current; if (!nav) return; const handleNavigation = (e: CustomEvent) => { const activeIndex = e.detail.activeIndex; const tabs = nav.querySelectorAll('md-navigation-tab'); const activeTab = tabs[activeIndex]; const href = activeTab?.getAttribute('data-href'); if (href) { router.push(href); } }; nav.addEventListener('navigation-tab-interaction', handleNavigation); return () => nav.removeEventListener('navigation-tab-interaction', handleNavigation); }, [router]); // Меню для ментора if (userRole === 'mentor') { return ( home home group group calendar_month calendar_month chat chat ); } // Аналогично для client и parent... return null; } ``` ### 4. Список студентов ```tsx 'use client'; export default function StudentsPage() { return (
person
Иван Иванов
ivan@example.com
more_vert
person
Петр Петров
petr@example.com
more_vert
); } ``` ### 5. Диалог (модальное окно) ```tsx 'use client'; import { useRef } from 'react'; export function CreateLessonDialog() { const dialogRef = useRef(null); const openDialog = () => { dialogRef.current?.show(); }; const closeDialog = () => { dialogRef.current?.close(); }; return ( <> Создать занятие
Новое занятие
Отмена Создать
); } ``` ### 6. Chips (фильтры) ```tsx 'use client'; export function FiltersBar() { return ( ); } ``` ### 7. Прогресс индикаторы ```tsx 'use client'; export function LoadingIndicator() { return (
); } export function UploadProgress({ value }: { value: number }) { return ( ); } ``` --- ## 🎨 Кастомизация под iOS 24+ стиль Создать файл `styles/ios-material.css`: ```css /* iOS 24+ адаптация для Material компонентов */ /* Bottom Navigation Bar */ md-navigation-bar { --md-navigation-bar-container-color: rgba(255, 255, 255, 0.8); --md-navigation-bar-container-height: 80px; backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-top: 0.5px solid rgba(0, 0, 0, 0.1); box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.08); border-radius: 24px 24px 0 0; position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000; } [data-theme="dark"] md-navigation-bar { --md-navigation-bar-container-color: rgba(28, 28, 30, 0.9); border-top-color: rgba(255, 255, 255, 0.1); } /* Cards с blur эффектом */ md-elevated-card { --md-elevated-card-container-color: rgba(255, 255, 255, 0.8); --md-elevated-card-container-shape: 20px; backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); } [data-theme="dark"] md-elevated-card { --md-elevated-card-container-color: rgba(28, 28, 30, 0.8); } /* Buttons с iOS стилем */ md-filled-button { --md-filled-button-container-shape: 16px; --md-filled-button-container-height: 48px; font-weight: 500; } /* Text Fields с iOS стилем */ md-outlined-text-field { --md-outlined-text-field-container-shape: 12px; --md-outlined-text-field-outline-width: 1px; } /* List Items с отступами */ md-list-item { --md-list-item-container-shape: 12px; margin: 4px 8px; } /* Dialogs с rounded corners */ md-dialog { --md-dialog-container-shape: 24px; } ``` --- ## 🌈 Material Icons Использовать Material Symbols из Google Fonts: ```html ``` **Использование:** ```tsx home calendar_month chat group settings ``` **Список популярных иконок:** - `home` - Главная - `calendar_month` - Календарь - `chat` - Чат - `group` - Студенты/Группы - `person` - Профиль - `settings` - Настройки - `notifications` - Уведомления - `payment` - Оплата - `school` - Обучение - `video_call` - Видеозвонок - `assignment` - Задания - `folder` - Материалы --- ## 📋 Типографика Material Design 3 ```html

Display Large

Display Medium

Display Small

Headline Large

Headline Medium

Headline Small

Body Large

Body Medium

Body Small

Label Large

Label Medium

Label Small

``` Импортировать типографику: ```typescript import { styles as typescaleStyles } from '@material/web/typography/md-typescale-styles.js'; // В layout.tsx useEffect(() => { document.adoptedStyleSheets.push(typescaleStyles.styleSheet); }, []); ``` --- ## 🎯 Важные замечания 1. **Web Components в React:** - Material Web Components - это нативные Web Components - Используются напрямую в JSX как HTML элементы - Не нужны wrapper компоненты 2. **События:** - Используйте `ref` для доступа к элементу - Добавляйте слушатели событий через `addEventListener` 3. **Стилизация:** - CSS Variables для кастомизации - Только чистый CSS, без Tailwind - Material Grid System для layout 4. **Компоненты из `labs`:** - Некоторые компоненты находятся в `@material/web/labs/` - Например: `navigation-bar`, `badge`, `card` --- **Документация:** https://github.com/material-components/material-web **Demo:** https://material-web.dev/