Rumah  >  Artikel  >  hujung hadapan web  >  Mencipta Komponen Dialog Peralihan Lancar dalam React (Bahagian )

Mencipta Komponen Dialog Peralihan Lancar dalam React (Bahagian )

WBOY
WBOYasal
2024-07-18 01:23:391044semak imbas

Creating a Smooth Transitioning Dialog Component in React (Part )

Bahagian 1: Menyediakan Komponen Dialog Asas dengan Minimumkan/Kembangkan Fungsi

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.

Menyediakan Komponen Dialog Asas

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

Langkah 1: Konteks Dialog

Mula-mula, saya akan mencipta konteks untuk mengurus keadaan komponen dialog kami.

Isi Penting:

  • DialogContext akan memegang keadaan dan menyediakan fungsi untuk menogol dialog antara keadaan diminimumkan dan dikembangkan.
  • Komponen DialogProvider memulakan keadaan dan memberikannya kepada komponen dialog melalui konteks.
// 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);
}

Langkah 2: Komponen Dialog

Seterusnya, saya akan mencipta komponen dialog utama yang menggunakan konteks untuk mengendalikan pengembangan dan pengecilan.

Isi Penting:

  • Komponen Dialog memulakan penyedia konteks dengan prop yang berkaitan.
  • Komponen gaya DialogComponent mengendalikan gaya asas dan reka letak dialog.
// 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;
`;

Langkah 3: Komponen Tambahan

Saya akan membuat komponen tambahan untuk pengepala dialog, kandungan, pengaki dan bekas untuk memastikan kemodulatan dan kebolehgunaan semula.

Isi Penting:

  • DialogHeader termasuk butang untuk menogol antara keadaan diminimumkan dan dikembangkan menggunakan konteks.
  • DialogContainer membungkus kandungan badan dan pengaki untuk menyembunyikannya secara automatik apabila nilai isExpanded ditukar.
  • Komponen DialogBody dan DialogFooter ialah bekas mudah untuk kandungan dialog.
// 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;
`;

Langkah 4: Menyatukan Semuanya

Akhir sekali, saya akan mengimport dan menggunakan komponen dialog dalam apl utama.

Isi Penting:

  • Komponen Apl termasuk Dialog dengan komponen pengepala, badan dan pengakinya.
  • Persediaan ini memastikan dialog sedia untuk peningkatan dan animasi selanjutnya dalam bahagian yang akan datang.
// 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:

Kesimpulan

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Teknologi FrontendArtikel seterusnya:Teknologi Frontend