”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 在 React 中创建平滑过渡的对话框组件(部分)

在 React 中创建平滑过渡的对话框组件(部分)

发布于2024-07-29
浏览:769

Creating a Smooth Transitioning Dialog Component in React (Part )

第 1 部分:设置具有最小化/展开功能的基本对话框组件

欢迎来到我的关于在 React 中创建响应式对话框组件的四部分系列的第一部分。在本系列中,我将探索不同的方法来实现平滑的动画过渡,同时保持对话框的流体尺寸。在最初的部分中,我将设置具有最小化和展开功能的基本对话框组件。

请注意,可访问性和响应式设计不属于本系列考虑因素的一部分。主要重点是创建具有平滑动画过渡的可重用对话框组件。

本系列是我一直致力于的概念验证的一部分,旨在讨论和完善 UI 组件动画技术。我邀请其他开发人员提供反馈和见解来验证我的方法或提出改进建议。

设置基本对话框组件

让我们首先创建一个支持最小化和扩展的高度可重用的对话框组件。我将使用组合模式来确保对话框可以适应不断变化的内容。

文件结构:

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

第 1 步:对话上下文

首先,我将创建一个上下文来管理对话框组件的状态。

关键点:

  • DialogContext 将保存状态并提供在最小化和展开状态之间切换对话框的功能。
  • DialogProvider 组件初始化状态并通过上下文将其提供给对话框组件。
// 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);
}

第2步:对话框组件

接下来,我将创建使用上下文来处理扩展和最小化的主对话框组件。

关键点:

  • Dialog 组件使用相关 props 初始化上下文提供程序。
  • DialogComponent 样式组件处理对话框的基本样式和布局。
// 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 (
    
      
        {children}
      
    
  );
}

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;
`;

第 3 步:附加组件

我将为对话框标题、正文、页脚和容器创建其他组件,以确保模块化和可重用性。

关键点:

  • DialogHeader 包含一个按钮,可使用上下文在最小化和展开状态之间切换。
  • DialogContainer 包装正文和页脚内容,以便在 isExpanded 值更改时自动隐藏它们。
  • DialogBody 和DialogFooter 组件是对话框内容的简单容器。
// 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 (
    
      
        {expandedTitle ?? children}
        
           setIsExpanded(false)}
          />
        
      
       setIsExpanded(true)}
      >
        {children}
        
          
        
      
    
  );
}

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 (
    
      {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 (
    
      
        
          {children}
        
      
    
  );
}

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 (
    
      
        {children}
      
    
  );
}

const DialogFooterComponent = styled.div`
  background: #f3f3f3;
`;

const DialogFooterContent = styled.div`
  padding: 8px 16px;
`;

第四步:把它们放在一起

最后,我将在主应用程序中导入并使用对话框组件。

关键点:

  • App 组件包括 Dialog 及其页眉、正文和页脚组件。
  • 此设置可确保对话框为后续部分中的进一步增强和动画做好准备。
// 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 (
    
My dialog/DialogHeader> This is the content of the dialog. This is the footer of the dialog.
); } 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 中设置了一个基本对话框,具有最小化和展开功能。这个基础组件将作为后续文章中进一步增强的基础。对话框组件旨在拥抱其内容并适应变化,使其具有高度可重用性和灵活性。

请继续关注第 2 部分,我将深入研究向对话框过渡添加动画,探索实现平滑效果的不同选项。

我邀请其他开发人员提供反馈和意见,以帮助完善和改进这种方法。您的见解对于使概念验证更加稳健和有效非常宝贵。

版本声明 本文转载于:https://dev.to/copet80/creating-a-smooth-transitioning-dialog-component-in-react-part-14-7nd?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python 导入编解码器 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有表情符号 emoji_pattern = re.compile(“ [”...
    编程 发布于2025-01-31
  • HTML格式标签
    HTML格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2025-01-31
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    [2最后一行与数据集中的每个不同标识符关联。考虑以下数据: 1 2014-02-01 kjkj 1 2014-03-11 ajskj 3 2014-02-01 sfdg 3 2014-06-12 fdsa 在(ID)上选择DISTINC 来自the_table 按ID订单,date desc;...
    编程 发布于2025-01-31
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    [2 _post ['ss'];?> 的目的是从单击提交按钮时,文本框并显示。但是,输出保持空白。当方法=“ get”无缝工作时,方法=“ post”构成问题。 检查action属性:如果您正在刷新页面,请将操作属性设置为空字符串,例如] action ='&#...
    编程 发布于2025-01-31
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式界面中实现垂直滚动元素的CSS高度限制 考虑一个布局,其中我们具有与可滚动的映射div一起移动的subollable map div用户的垂直滚动,同时保持其与固定侧边栏的对齐方式。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。 可以限制地图的滚动,我们可以利用CSS...
    编程 发布于2025-01-31
  • 如何从Google API中检索最新的jQuery库?
    如何从Google API中检索最新的jQuery库?
    从Google APIS 问题中提供的jQuery URL是版本1.2.6。对于检索最新版本,以前有一种使用特定版本号的替代方法,它是使用以下语法: https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js(google hosted...
    编程 发布于2025-01-31
  • 如何在整个HTML文档中设计特定元素类型的第一个实例?
    如何在整个HTML文档中设计特定元素类型的第一个实例?
    [2单独使用CSS,整个HTML文档可能是一个挑战。 the:第一型伪级仅限于与其父元素中类型的第一个元素匹配。 以下CSS将使用添加的类样式的第一个段落: }
    编程 发布于2025-01-31
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月份)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将...
    编程 发布于2025-01-31
  • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    插入记录时如何解决“一般错误:2006 MySQL 服务器已消失”介绍:将数据插入 MySQL 数据库有时会导致错误“一般错误:2006 MySQL 服务器已消失”。当与服务器的连接丢失时会出现此错误,通常是由于 MySQL 配置中的两个变量之一所致。解决方案:解决此错误的关键是调整wait_tim...
    编程 发布于2025-01-31
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    在这里工作/},false); 不幸的是,答案是否。除非在Creation中存储对处理程序的引用。要解决此问题,请考虑将事件处理程序存储在中心位置,例如页面的主要对象,请考虑将事件处理程序存储在中心位置,否则无法清理匿名事件处理程序。 。这允许在需要时轻松迭代和清洁处理程序。
    编程 发布于2025-01-31
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php 您的目标可能是检索“ varnum”属性值,其中提取数据的传统方法可能会使您感到困惑。 - > attributes()为$ attributeName => $ attributeValue){ echo $ attributeName,'=“',$ at...
    编程 发布于2025-01-31
  • 如何使用char_length()在mySQL中按字符串长度对数据进行排序?
    如何使用char_length()在mySQL中按字符串长度对数据进行排序?
    [2 using the built-in CHAR_LENGTH() function.Difference between CHAR_LENGTH() and LENGTH()CHAR_LENGTH():返回字符串中字符数的数量,考虑多字节字符编码(例如,UTF-8)。 此查询将从指定的表中检...
    编程 发布于2025-01-31
  • 大批
    大批
    [2 数组是对象,因此它们在JS中也具有方法。 切片(开始):在新数组中提取部分数组,而无需突变原始数组。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    编程 发布于2025-01-31
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    解决此问题,我们采用了一个巧妙的CSS解决方案来解决问题: transform:translate:translate(-50%,-50%); height:100%; 高度:auto; 宽度:100%; //对于水平块 ,使用绝对定位将图像定位在中心,以object-fit:object-f...
    编程 发布于2025-01-31
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    </main> <section> ,但无法使其正常工作,如您所见。任何洞察力都将不胜感激! display:grid; { position:sticky; top:1em; z-index:1 1 ; { { { pos...
    编程 发布于2025-01-31

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3