Добро пожаловать в первую часть моей серии из четырех частей, посвященной созданию адаптивного диалогового компонента в React. В этой серии я рассмотрю различные подходы к достижению плавных анимационных переходов, сохраняя при этом плавные размеры диалога. В этой начальной части я настрою базовый компонент диалогового окна с функциями свертывания и расширения.
Обратите внимание, что доступность и адаптивный дизайн не рассматриваются в этой серии статей. Основное внимание уделяется созданию многократно используемого диалогового компонента с плавными анимационными переходами.
Эта серия является частью проверки концепции, над которой я работаю, и направлена на обсуждение и совершенствование методов анимации компонентов пользовательского интерфейса. Я приглашаю коллег-разработчиков получить отзывы и идеи, чтобы подтвердить мой подход или предложить улучшения.
Давайте начнем с создания многоразового диалогового компонента, поддерживающего свертывание и раскрытие. Я буду использовать композиционный шаблон, чтобы диалог мог адаптироваться к изменяющемуся содержанию.
Структура файла:
src/ components/ FluidDialog/ Dialog.js DialogContext.js DialogHeader.js DialogBody.js DialogFooter.js DialogContainer.js index.js App.js index.js
Сначала я создам контекст для управления состоянием нашего диалогового компонента.
Ключевые моменты:
// src/components/FluidDialog/DialogContext.js import { createContext, useContext, useId, useState } from 'react'; const DialogContext = createContext(); export function DialogProvider({ rootRef, isExpandedByDefault, children, maxWidth, }) { const dialogId = useId(); const [isExpanded, setIsExpanded] = useState(isExpandedByDefault); return ({children} ); } export function useDialog() { return useContext(DialogContext); }
Далее я создам основной компонент диалогового окна, который использует контекст для управления расширением и минимизацией.
Ключевые моменты:
// src/components/FluidDialog/Dialog.js import { useRef } from 'react'; import { styled } from 'styled-components'; import { DialogProvider } from './DialogContext'; export default function Dialog({ id, isExpandedByDefault = true, maxWidth = 400, children, }) { const rootRef = useRef(null); return (); } const DialogComponent = styled.section` max-width: ${({ maxWidth }) => (maxWidth ? `${maxWidth}px` : undefined)}; position: absolute; right: 16px; bottom: 16px; border: 1px solid #ccc; border-radius: 6px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.35); overflow: hidden; `; {children}
Я создам дополнительные компоненты для заголовка, тела, нижнего колонтитула и контейнера диалогового окна, чтобы обеспечить модульность и возможность повторного использования.
Ключевые моменты:
// src/components/FluidDialog/DialogHeader.js import { styled } from 'styled-components'; import { IconButton } from '../IconButton'; import { useDialog } from './DialogContext'; export default function DialogHeader({ children, expandedTitle }) { const { dialogId, isExpanded, setIsExpanded } = useDialog(); return (); } const DialogHeaderComponent = styled.div``; const ExpandedState = styled.header` transition: opacity 0.3s; opacity: ${({ isVisible }) => (isVisible ? 1 : 0)}; pointer-events: ${({ isVisible }) => (isVisible ? 'all' : 'none')}; position: absolute; top: 0; left: 0; width: 100%; background: #f3f3f3; display: flex; flex-direction: row; `; const MinimizedState = styled.header` transition: opacity 0.3s; opacity: ${({ isVisible }) => (isVisible ? 1 : 0)}; pointer-events: ${({ isVisible }) => (isVisible ? 'all' : 'none')}; background: #f3f3f3; display: flex; flex-direction: row; cursor: pointer; `; const Title = styled.span` flex-grow: 1; text-align: left; display: flex; align-items: center; padding: 0 16px; `; const IconButtons = styled.div``; {expandedTitle ?? children} setIsExpanded(false)} /> setIsExpanded(true)} > {children}
// src/components/FluidDialog/DialogContainer.js import { styled } from 'styled-components'; import { useDialog } from './DialogContext'; export default function DialogContainer({ children }) { const { isExpanded } = useDialog(); return ({children} ); } const DialogContainerComponent = styled.div` display: ${({ isVisible }) => (isVisible ? undefined : 'none')}; `;
// src/components/FluidDialog/DialogBody.js import { styled } from 'styled-components'; import DialogContainer from './DialogContainer'; import { useDialog } from './DialogContext'; export default function DialogBody({ children }) { const { dialogId } = useDialog(); return (); } const DialogBodyComponent = styled.div``; const DialogBodyContent = styled.div` padding: 8px 16px; `; {children}
// src/components/FluidDialog/DialogFooter.js import { styled } from 'styled-components'; import DialogContainer from './DialogContainer'; export default function DialogFooter({ children }) { return (); } const DialogFooterComponent = styled.div` background: #f3f3f3; `; const DialogFooterContent = styled.div` padding: 8px 16px; `; {children}
Наконец, я импортирую и использую компонент диалога в основном приложении.
Ключевые моменты:
// src/App.js import React from 'react'; import Dialog from './components/FluidDialog/Dialog'; import DialogHeader from './components/FluidDialog/DialogHeader'; import DialogBody from './components/FluidDialog/DialogBody'; import DialogFooter from './components/FluidDialog/DialogFooter'; function App() { return (); } export default App;
// src/index.js import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; ReactDOM.render(, document.getElementById('root') );
Вы можете получить доступ ко всему исходному коду на CodeSandbox.
Вы также можете просмотреть предварительный просмотр реализации:
В этой первой части я настроил базовое диалоговое окно в React с функциями свертывания и расширения. Этот основополагающий компонент послужит основой для дальнейших улучшений в следующих статьях. Диалоговый компонент спроектирован так, чтобы охватывать его содержимое и адаптироваться к изменениям, что делает его многоразовым и гибким.
Следите за обновлениями во второй части, где я расскажу о добавлении анимации к диалоговым переходам и изучении различных вариантов достижения плавных эффектов.
Я жду отзывов и комментариев от коллег-разработчиков, которые помогут усовершенствовать и улучшить этот подход. Ваши идеи неоценимы и помогут сделать это доказательство концепции более надежным и эффективным.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3