0.0.2 • Published 10 months ago

@nnnb/prompt v0.0.2

Weekly downloads
-
License
MIT
Repository
-
Last release
10 months ago

@nnnb/prompt

一个用于 React 应用中 各种组件的灵活弹层管理解决方案。

特性

  • 🚀 简单易用的弹窗系统,支持 Modal、Drawer 等弹层组件
  • 🎯 支持全局和局部上下文渲染
  • ⚡ 高效的弹层管理,自动清理资源
  • 🛠️ 使用 TypeScript 实现类型安全
  • 🔄 可复用的弹层组件,支持自定义配置
  • 📊 支持异步获取弹层组件的返回值

安装

npm install @nnnb/prompt
# 或
yarn add @nnnb/prompt

使用方法

基础用法

import { createPrompt } from '@nnnb/prompt';
import { Modal } from 'antd';

// 创建一个带默认配置的 Modal 提示框
const ModalPrompt = createPrompt(Modal, {
  centered: true,
  destroyOnClose: true
});

// 使用 Modal 提示框
const showModal = async () => {
  const result = await ModalPrompt({
    props:{  
      title: '示例弹窗',
      content: '这是一个弹窗内容'
    }
  });
  console.log(result);
};

使用案例

1. 简单使用

创建并显示一个 Modal,支持自定义组件和获取返回值:

import React from 'react';
import { createPrompt } from '@nnnb/prompt';
import { Button, Input, Modal } from 'antd';

// 创建一个 Modal 提示框
const ModalPrompt = createPrompt(Modal, {
  centered: true,
  destroyOnClose: true
});

// 自定义表单组件
const FormA = ({ A, B }) => {
  return (
    <div>
      <div>
        A: <Input defaultValue={A} />
      </div>
      <div>
        B: <Input defaultValue={B} />
      </div>
    </div>
  );
};

const Form = () => {
  const createModal = async () => {
    const res = await ModalPrompt({
      component: FormA,
      props: {
        title: 'Modal',
        onOk: (e) => {
          console.log('onOk', e);
          return {
            a: 'a'
          };
        },
        onCancel: () => {
          console.log('onCancel');
        }
      },
      data: {
        A: 'AAAA',
        B: 'BBBB'
      }
    });

    console.log(res); // 获取返回值
  };
  
  return (
    <div>
      <Button onClick={() => createModal()}>创建 Modal</Button>
    </div>
  );
};

2. 使用 Ant Design 的全局配置

在 ConfigProvider 中使用弹层,继承全局主题配置:

import React from 'react';
import { LayerContextProvider, createPrompt } from '@nnnb/prompt';
import { Button, ConfigProvider, Input, Modal } from 'antd';

const ModalPrompt = createPrompt(Modal, {
  centered: true,
  destroyOnClose: true
});

// 自定义表单组件
const FormA = ({ A, B }) => {
  return (
    <div>
      <div>
        A: <Input defaultValue={A} />
      </div>
      <div>
        B: <Input defaultValue={B} />
      </div>
    </div>
  );
};

const Form = () => {
  const createModal = () => {
    ModalPrompt({
      component: FormA,
      props: {
        title: 'Modal'
      },
      data: {
        A: 'AAAA',
        B: 'BBBB'
      }
    });
  };
  
  return (
    <div>
      <Button onClick={() => createModal()}>创建 Modal</Button>
    </div>
  );
};

// 在应用中使用
function App() {
  const [open, setOpen] = React.useState(false);
  
  return (
    <ConfigProvider
      theme={{
        token: {
          colorPrimary: '#006603',
          borderRadius: 6
        },
        components: {
          Button: {
            colorPrimary: '#00B96B'
          }
        }
      }}
    >
      <div>
        <Button onClick={() => setOpen(!open)}>显示</Button>
        <div>{open && <LayerContextProvider />}</div>
      </div>
      <Form />
    </ConfigProvider>
  );
}

3. 自定义渲染位置

使用 usePrompt 钩子获取 holder 来控制弹层渲染位置:

import React from 'react';
import { usePrompt } from '@nnnb/prompt';
import { Button, ConfigProvider, Drawer, Input, Modal } from 'antd';

// 自定义表单组件
const FormA = ({ A, B }) => {
  return (
    <div>
      <div>
        A: <Input defaultValue={A} />
      </div>
      <div>
        B: <Input defaultValue={B} />
      </div>
    </div>
  );
};

const Form = ({ ModalPrompt }) => {
  const createModal = () => {
    ModalPrompt({
      component: FormA,
      props: {
        title: 'Modal'
      },
      data: {
        A: 'AAAA',
        B: 'BBBB'
      }
    });
  };
  
  return (
    <div>
      <Button type="primary" onClick={() => createModal()}>创建 Modal</Button>
    </div>
  );
};

function App() {
  // 获取 Modal 的 holder 和 prompt 函数
  const [holder, prompt] = usePrompt(Modal);
  
  // 获取 Drawer 的 holder 和 prompt 函数
  const [holder2, prompt2] = usePrompt(Drawer);

  return (
    <div>
      {/* Modal 将在这里渲染 */}
      {holder}
      
      <ConfigProvider
        theme={{
          token: {
            colorPrimary: '#006603',
            borderRadius: 6
          }
        }}
      >
        {/* Drawer 将在这里渲染,会继承 ConfigProvider 的样式 */}
        {holder2}
        
        <Form ModalPrompt={prompt} />
        <Form ModalPrompt={prompt2} />
      </ConfigProvider>
    </div>
  );
}

4. 高级用法 - 异步获取子组件返回值

通过 refuseImperativeHandle 实现异步获取子组件值:

import React, { ForwardRefRenderFunction, useImperativeHandle } from 'react';
import { PromptModalRef, usePrompt } from '@nnnb/prompt';
import { Button, Input, Modal } from 'antd';

// 延迟函数,模拟异步操作
const delay = (time: number) => new Promise((resolve) => setTimeout(resolve, time));

// 自定义表单组件,通过 ref 暴露方法
const FormA: ForwardRefRenderFunction<PromptModalRef, any> = ({ A, B }, ref) => {
  useImperativeHandle(ref, () => ({
    // 定义 onOk 方法,将在点击确定按钮时调用
    onOk: async () => {
      await delay(2000); // 模拟异步操作,比如数据验证或提交
      return 'a'; // 返回值将作为 ModalPrompt 的结果
    }
  }));
  
  return (
    <div>
      <div>
        A: <Input defaultValue={A} />
      </div>
      <div>
        B: <Input defaultValue={B} />
      </div>
    </div>
  );
};

const Form = ({ ModalPrompt }) => {
  const createModal = async () => {
    // 等待弹窗操作完成,获取返回值
    const val = await ModalPrompt({
      component: FormA,
      props: {
        title: 'Modal',
        onOk: (e) => {
          console.log('Form', e);
        }
      },
      data: {
        A: 'AAAA',
        B: 'BBBB'
      }
    });
    
    console.log(val); // 输出 'a'
  };
  
  return (
    <div>
      <Button type="primary" onClick={() => createModal()}>创建 Modal</Button>
    </div>
  );
};

function App() {
  const [holder, prompt] = usePrompt(Modal);

  return (
    <div>
      {holder}
      <Form ModalPrompt={prompt} />
    </div>
  );
}

API 文档

createPrompt

createPrompt<ComponentProps extends PromptBaseModalProps, ReturnType = any>(
  Component: ComponentType<ComponentProps>,
  defaultConfig?: Partial<ComponentProps>
) => PromptFunction

创建一个新的提示框函数,可以指定组件和默认配置。

usePrompt

usePrompt<P>(
  Component: ComponentType<P>,
  defaultConfig?: Partial<P>
): [ReactNode, PromptFunction]

返回一个元组,包含渲染占位符和提示函数。

LayerContextProvider

<LayerContextProvider />

全局上下文提供者,用于在特定位置渲染弹层组件。

PromptModalRef 接口

interface PromptModalRef {
  onOk?: () => Promise<any> | any;
  onCancel?: () => void;
}

用于在自定义组件中通过 ref 暴露方法。

类型定义

interface PromptBaseModalProps {
  open?: boolean;
  confirmLoading?: boolean;
  onOk?: (e: any) => void | Promise<any>;
  onCancel?: (e: any) => void;
  children?: ReactNode;
}

贡献指南

欢迎提交 Pull Request 来帮助改进这个项目!

许可证

MIT

0.0.2

10 months ago

1.0.0

2 years ago