React でのレスポンシブ ダイアログ コンポーネントの作成に関する 4 部構成のシリーズの最初の部分へようこそ。このシリーズでは、ダイアログの流動的な寸法を維持しながら、アニメーションのスムーズな移行を実現するためのさまざまなアプローチを検討します。この最初の部分では、最小化および展開機能を備えた基本的なダイアログ コンポーネントをセットアップします。
アクセシビリティとレスポンシブ デザインは、このシリーズの考慮事項の一部として含まれていないことに注意してください。主な焦点は、スムーズなアニメーション遷移を備えた再利用可能なダイアログ コンポーネントを作成することです。
このシリーズは、UI コンポーネントをアニメーション化するための技術について議論し洗練することを目的として、私が取り組んでいる概念実証の一部です。私のアプローチを検証したり、改善点を提案したりするために、他の開発者からのフィードバックや洞察を求めています。
まず、最小化と展開をサポートする再利用性の高いダイアログ コンポーネントを作成しましょう。構成パターンを使用して、ダイアログがコンテンツの変化に確実に適応できるようにします。
ファイル構造:
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 ( <DialogContext.Provider value={{ dialogId, rootRef, isExpanded, setIsExpanded, maxWidth }} > {children} </DialogContext.Provider> ); } 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 ( <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; `;
モジュール性と再利用性を確保するために、ダイアログ ヘッダー、本文、フッター、およびコンテナー用の追加コンポーネントを作成します。
キーポイント:
// 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; `;
最後に、ダイアログ コンポーネントをメイン アプリにインポートして使用します。
キーポイント:
// 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') );
CodeSandbox でソース コード全体にアクセスできます。
実装のライブ プレビューを確認することもできます:
この最初のパートでは、最小化および展開機能を備えた基本的なダイアログ ボックスを React にセットアップしました。この基本コンポーネントは、今後の記事でさらに機能強化するための基礎として機能します。ダイアログ コンポーネントは、コンテンツを受け入れて変更に適応するように設計されているため、再利用性と柔軟性が高くなります。
パート 2 では、ダイアログ トランジションへのアニメーションの追加について詳しく説明し、スムーズな効果を実現するためのさまざまなオプションを検討します。
このアプローチを改良し改善するために、他の開発者からのフィードバックやコメントを歓迎します。この概念実証をより堅牢かつ効果的にするために、皆様の洞察は非常に貴重です。
以上がReact でスムーズに移行するダイアログ コンポーネントを作成する (パート )の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。