Rumah >hujung hadapan web >tutorial css >Mencipta Komponen Dialog Peralihan Lancar dalam React (Bahagian )
Selamat datang ke bahagian pertama siri empat bahagian saya tentang mencipta komponen dialog responsif dalam React. Dalam siri ini, saya akan meneroka pendekatan yang berbeza untuk mencapai peralihan animasi yang lancar sambil mengekalkan dimensi bendalir dialog. Dalam bahagian awal ini, saya akan menyediakan komponen dialog asas dengan meminimumkan dan mengembangkan fungsi.
Sila ambil perhatian bahawa kebolehcapaian dan reka bentuk responsif tidak disertakan sebagai sebahagian daripada pertimbangan dalam siri ini. Fokus utama ialah mencipta komponen dialog boleh guna semula dengan peralihan animasi yang lancar.
Siri ini adalah sebahagian daripada bukti konsep yang saya usahakan, bertujuan untuk membincangkan dan memperhalusi teknik untuk menghidupkan komponen UI. Saya menjemput maklum balas dan cerapan daripada rakan pembangun untuk mengesahkan pendekatan saya atau mencadangkan penambahbaikan.
Mari kita mulakan dengan mencipta komponen dialog yang sangat boleh digunakan semula yang menyokong pengurangan dan pengembangan. Saya akan menggunakan corak gubahan untuk memastikan dialog boleh menyesuaikan diri dengan perubahan kandungan.
Struktur Fail:
src/ components/ FluidDialog/ Dialog.js DialogContext.js DialogHeader.js DialogBody.js DialogFooter.js DialogContainer.js index.js App.js index.js
Mula-mula, saya akan mencipta konteks untuk mengurus keadaan komponen dialog kami.
Isi Penting:
// 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 ( <DialogContext.Provider value={{ dialogId, rootRef, isExpanded, setIsExpanded, maxWidth }} > {children} </DialogContext.Provider> ); } export function useDialog() { return useContext(DialogContext); }
Seterusnya, saya akan mencipta komponen dialog utama yang menggunakan konteks untuk mengendalikan pengembangan dan pengecilan.
Isi Penting:
// 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 ( <DialogProvider dialogId={id} rootRef={rootRef} isExpandedByDefault={isExpandedByDefault} > <DialogComponent role="dialog" aria-labelledby={`${id}_label`} aria-describedby={`${id}_desc`} ref={rootRef} maxWidth={maxWidth} > {children} </DialogComponent> </DialogProvider> ); } 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; `;
Saya akan membuat komponen tambahan untuk pengepala dialog, kandungan, pengaki dan bekas untuk memastikan kemodulatan dan kebolehgunaan semula.
Isi Penting:
// 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 ( <DialogHeaderComponent id={`${dialogId}_label`}> <ExpandedState isVisible={isExpanded}> <Title>{expandedTitle ?? children}</Title> <IconButtons> <IconButton icon="chevron-down" onClick={() => setIsExpanded(false)} /> </IconButtons> </ExpandedState> <MinimizedState isVisible={!isExpanded} onClick={() => setIsExpanded(true)} > <Title>{children}</Title> <IconButtons> <IconButton icon="chevron-up" /> </IconButtons> </MinimizedState> </DialogHeaderComponent> ); } 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``;
// src/components/FluidDialog/DialogContainer.js import { styled } from 'styled-components'; import { useDialog } from './DialogContext'; export default function DialogContainer({ children }) { const { isExpanded } = useDialog(); return ( <DialogContainerComponent isVisible={isExpanded}> {children} </DialogContainerComponent> ); } 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 ( <DialogBodyComponent> <DialogContainer> <DialogBodyContent id={`${dialogId}_desc`}> {children} </DialogBodyContent> </DialogContainer> </DialogBodyComponent> ); } const DialogBodyComponent = styled.div``; const DialogBodyContent = styled.div` padding: 8px 16px; `;
// src/components/FluidDialog/DialogFooter.js import { styled } from 'styled-components'; import DialogContainer from './DialogContainer'; export default function DialogFooter({ children }) { return ( <DialogFooterComponent> <DialogContainer> <DialogFooterContent>{children}</DialogFooterContent> </DialogContainer> </DialogFooterComponent> ); } const DialogFooterComponent = styled.div` background: #f3f3f3; `; const DialogFooterContent = styled.div` padding: 8px 16px; `;
Akhir sekali, saya akan mengimport dan menggunakan komponen dialog dalam apl utama.
Isi Penting:
// 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 ( <div className="App"> <Dialog> <DialogHeader>My dialog/DialogHeader> <DialogBody>This is the content of the dialog.</DialogBody> <DialogFooter>This is the footer of the dialog.</DialogFooter> </Dialog> </div> ); } export default App;
// src/index.js import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
Anda boleh mengakses keseluruhan kod sumber pada CodeSandbox.
Anda juga boleh melihat pratonton langsung pelaksanaan:
Dalam bahagian pertama ini, saya telah menyediakan kotak dialog asas dalam React dengan meminimumkan dan mengembangkan fungsi. Komponen asas ini akan menjadi asas untuk penambahbaikan selanjutnya dalam artikel yang akan datang. Komponen dialog direka bentuk untuk menerima kandungannya dan menyesuaikan diri dengan perubahan, menjadikannya sangat boleh digunakan semula dan fleksibel.
Nantikan Bahagian 2, di mana saya akan mendalami menambah animasi pada peralihan dialog, meneroka pilihan yang berbeza untuk mencapai kesan lancar.
Saya menjemput maklum balas dan komen daripada rakan pembangun untuk membantu memperhalusi dan menambah baik pendekatan ini. Cerapan anda tidak ternilai dalam menjadikan bukti konsep ini lebih mantap dan berkesan.
Atas ialah kandungan terperinci Mencipta Komponen Dialog Peralihan Lancar dalam React (Bahagian ). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!