Heim  >  Artikel  >  Web-Frontend  >  Erstellen einer Dialogkomponente mit sanften Übergängen in React (Teil)

Erstellen einer Dialogkomponente mit sanften Übergängen in React (Teil)

WBOY
WBOYOriginal
2024-07-18 01:23:391124Durchsuche

Creating a Smooth Transitioning Dialog Component in React (Part )

Teil 1: Einrichten der grundlegenden Dialogkomponente mit Minimieren/Erweitern-Funktionalität

Willkommen zum ersten Teil meiner vierteiligen Serie zum Erstellen einer responsiven Dialogkomponente in React. In dieser Serie werde ich verschiedene Ansätze untersuchen, um reibungslose Animationsübergänge zu erzielen und gleichzeitig die fließenden Dimensionen des Dialogs beizubehalten. In diesem ersten Teil richte ich die grundlegende Dialogkomponente mit Minimierungs- und Erweiterungsfunktionen ein.

Bitte beachten Sie, dass Barrierefreiheit und responsives Design nicht Teil der Überlegungen dieser Serie sind. Das Hauptaugenmerk liegt auf der Erstellung einer wiederverwendbaren Dialogkomponente mit reibungslosen Animationsübergängen.

Diese Serie ist Teil eines Proof of Concept, an dem ich gearbeitet habe und dessen Ziel es ist, Techniken zur Animation von UI-Komponenten zu diskutieren und zu verfeinern. Ich bitte um Feedback und Erkenntnisse von anderen Entwicklern, um meinen Ansatz zu validieren oder Verbesserungen vorzuschlagen.

Einrichten der Basisdialogkomponente

Beginnen wir mit der Erstellung einer hoch wiederverwendbaren Dialogkomponente, die das Minimieren und Erweitern unterstützt. Ich werde das Kompositionsmuster verwenden, um sicherzustellen, dass sich der Dialog an sich ändernde Inhalte anpassen kann.

Dateistruktur:

src/
  components/
    FluidDialog/
      Dialog.js
      DialogContext.js
      DialogHeader.js
      DialogBody.js
      DialogFooter.js
      DialogContainer.js
      index.js
  App.js
  index.js

Schritt 1: Dialogkontext

Zuerst erstelle ich einen Kontext, um den Status unserer Dialogkomponente zu verwalten.

Wichtige Punkte:

  • Der DialogContext speichert den Status und stellt Funktionen bereit, um den Dialog zwischen minimiertem und erweitertem Status umzuschalten.
  • Die DialogProvider-Komponente initialisiert den Zustand und stellt ihn den Dialogkomponenten per Kontext zur Verfügung.
// 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);
}

Schritt 2: Dialogkomponente

Als nächstes erstelle ich die Hauptdialogkomponente, die den Kontext für die Erweiterung und Minimierung verwendet.

Wichtige Punkte:

  • Die Dialogkomponente initialisiert den Kontextanbieter mit relevanten Requisiten.
  • Die DialogComponent-Stilkomponente verwaltet den grundlegenden Stil und das Layout des Dialogs.
// 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;
`;

Schritt 3: Zusätzliche Komponenten

Ich erstelle zusätzliche Komponenten für die Dialogkopfzeile, den Textkörper, die Fußzeile und den Container, um Modularität und Wiederverwendbarkeit sicherzustellen.

Wichtige Punkte:

  • DialogHeader enthält eine Schaltfläche zum Umschalten zwischen minimiertem und erweitertem Status mithilfe des Kontexts.
  • DialogContainer umschließt den Text- und Fußzeileninhalt, um ihn automatisch auszublenden, wenn der isExpanded-Wert geändert wird.
  • Die Komponenten DialogBody und DialogFooter sind einfache Container für den Inhalt des Dialogs.
// 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;
`;

Schritt 4: Alles zusammenfügen

Zuletzt importiere und verwende ich die Dialogkomponente in der Haupt-App.

Wichtige Punkte:

  • Die App-Komponente umfasst den Dialog mit seinen Kopf-, Text- und Fußzeilenkomponenten.
  • Dieses Setup stellt sicher, dass der Dialog für weitere Verbesserungen und Animationen in den kommenden Teilen bereit ist.
// 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')
);

Sie können auf den gesamten Quellcode auf CodeSandbox zugreifen.

Sie können auch eine Live-Vorschau der Umsetzung sehen:

Abschluss

In diesem ersten Teil habe ich in React ein einfaches Dialogfeld mit Minimierungs- und Erweiterungsfunktionen eingerichtet. Diese grundlegende Komponente wird als Grundlage für weitere Verbesserungen in den kommenden Artikeln dienen. Die Dialogkomponente ist so konzipiert, dass sie sich an den Inhalt anpasst und sich an Änderungen anpasst, wodurch sie äußerst wiederverwendbar und flexibel ist.

Bleiben Sie gespannt auf Teil 2, in dem ich mich mit dem Hinzufügen von Animationen zu den Dialogübergängen befasse und verschiedene Optionen erkunde, um reibungslose Effekte zu erzielen.

Ich bitte um Feedback und Kommentare von anderen Entwicklern, um diesen Ansatz zu verfeinern und zu verbessern. Ihre Erkenntnisse sind von unschätzbarem Wert, um diesen Proof of Concept robuster und effektiver zu machen.

Das obige ist der detaillierte Inhalt vonErstellen einer Dialogkomponente mit sanften Übergängen in React (Teil). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Frontend-TechnologienNächster Artikel:Frontend-Technologien