مرحبًا بك في الجزء الأول من سلسلتي المكونة من أربعة أجزاء حول إنشاء مكون حوار سريع الاستجابة في 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