diff --git a/.changeset/little-rabbits-change.md b/.changeset/little-rabbits-change.md new file mode 100644 index 000000000..bae3e287c --- /dev/null +++ b/.changeset/little-rabbits-change.md @@ -0,0 +1,12 @@ +--- +"@hi-ui/core": patch +"@hi-ui/container-context": patch +"@hi-ui/drawer": patch +"@hi-ui/hiui": patch +"@hi-ui/loading": patch +"@hi-ui/modal": patch +"@hi-ui/preview": patch +"@hi-ui/provider": patch +--- + +feat(container-context): add container package (#3060) diff --git a/packages/core/core/package.json b/packages/core/core/package.json index 51d288763..5cb6117c0 100644 --- a/packages/core/core/package.json +++ b/packages/core/core/package.json @@ -45,6 +45,7 @@ "devDependencies": {}, "dependencies": { "@hi-ui/core-css": "^4.1.5", - "@hi-ui/locale-context": "^4.0.8" + "@hi-ui/locale-context": "^4.0.8", + "@hi-ui/container-context": "^4.0.0" } } diff --git a/packages/core/core/src/index.ts b/packages/core/core/src/index.ts index e9f7afbbd..2386c22bf 100644 --- a/packages/core/core/src/index.ts +++ b/packages/core/core/src/index.ts @@ -73,3 +73,6 @@ export type HiBaseSizeEnum = ValueOf // 将 core 设为 peer:保证 context 实例引用一致性 export { useLocaleContext, LocaleProvider } from '@hi-ui/locale-context' export type { UseLocaleContext, LocaleProviderProps } from '@hi-ui/locale-context' + +export { useContainerContext, ContainerProvider } from '@hi-ui/container-context' +export type { UseContainerContext, ContainerProviderProps } from '@hi-ui/container-context' diff --git a/packages/ui/container-context/CHANGELOG.md b/packages/ui/container-context/CHANGELOG.md new file mode 100644 index 000000000..66989f062 --- /dev/null +++ b/packages/ui/container-context/CHANGELOG.md @@ -0,0 +1,7 @@ +# @hi-ui/locale-context + +## 4.0.0 + +### Patch Changes + +- [#2393](https://github.com/XiaoMi/hiui/pull/2393) [`a7d47168b`](https://github.com/XiaoMi/hiui/commit/a7d47168b519cacfd7b34edf6ba239c5b0b92284) Thanks [@zyprepare](https://github.com/zyprepare)! - 优化多语言获取文案时的空值判断 diff --git a/packages/ui/container-context/README.md b/packages/ui/container-context/README.md new file mode 100644 index 000000000..3e227121e --- /dev/null +++ b/packages/ui/container-context/README.md @@ -0,0 +1,11 @@ +# `@hi-ui/container-context` + +> TODO: description + +## Usage + +``` +const ContainerContext = require('@hi-ui/container-context'); + +// TODO: DEMONSTRATE API +``` diff --git a/packages/ui/container-context/__tests__/locale-context.test.js b/packages/ui/container-context/__tests__/locale-context.test.js new file mode 100644 index 000000000..1280afc6d --- /dev/null +++ b/packages/ui/container-context/__tests__/locale-context.test.js @@ -0,0 +1,5 @@ +const ContainerContext = require('../src') + +describe('@hi-ui/container-context', () => { + it('needs tests', () => {}) +}) diff --git a/packages/ui/container-context/hi-docs.config.mdx b/packages/ui/container-context/hi-docs.config.mdx new file mode 100644 index 000000000..dfe717b4c --- /dev/null +++ b/packages/ui/container-context/hi-docs.config.mdx @@ -0,0 +1,15 @@ +# ContainerContext 语言上下文 + +容器设置上下文。 + +## 何时使用 + +组件使用场景中文介绍 + +## 使用示例 + + + +## Props + + diff --git a/packages/ui/container-context/jest.config.js b/packages/ui/container-context/jest.config.js new file mode 100644 index 000000000..e33c14b5d --- /dev/null +++ b/packages/ui/container-context/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../../jest.config') diff --git a/packages/ui/container-context/package.json b/packages/ui/container-context/package.json new file mode 100644 index 000000000..e0b3e0802 --- /dev/null +++ b/packages/ui/container-context/package.json @@ -0,0 +1,54 @@ +{ + "name": "@hi-ui/container-context", + "version": "4.0.0", + "description": "A sub-package for @hi-ui/hiui.", + "keywords": [], + "author": "HiUI ", + "homepage": "https://github.com/XiaoMi/hiui/tree/master/packages/ui/container-context#readme", + "license": "MIT", + "directories": { + "lib": "lib", + "test": "__tests__" + }, + "files": [ + "lib" + ], + "main": "lib/cjs/index.js", + "module": "lib/esm/index.js", + "types": "lib/types/index.d.ts", + "typings": "lib/types/index.d.ts", + "exports": { + ".": { + "require": "./lib/cjs/index.js", + "default": "./lib/esm/index.js" + } + }, + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/XiaoMi/hiui.git" + }, + "scripts": { + "test": "jest", + "clean": "rimraf lib", + "prebuild": "yarn clean", + "build:esm": "hi-build ./src/index.ts --format esm -d ./lib/esm", + "build:cjs": "hi-build ./src/index.ts --format cjs -d ./lib/cjs", + "build:types": "tsc --emitDeclarationOnly --declaration --declarationDir lib/types", + "build": "concurrently yarn:build:*" + }, + "bugs": { + "url": "https://github.com/XiaoMi/hiui/issues" + }, + "dependencies": {}, + "peerDependencies": { + "react": ">=16.8.6", + "react-dom": ">=16.8.6" + }, + "devDependencies": { + "react": "^17.0.1", + "react-dom": "^17.0.1" + } +} diff --git a/packages/ui/container-context/src/ContainerContext.tsx b/packages/ui/container-context/src/ContainerContext.tsx new file mode 100644 index 000000000..6d74605f8 --- /dev/null +++ b/packages/ui/container-context/src/ContainerContext.tsx @@ -0,0 +1,11 @@ +import { createContext, useContext } from 'react' + +export const ContainerContext = createContext(null) + +export const useContainerContext = () => { + const context = useContext(ContainerContext) + + return context +} + +export type UseContainerContext = HTMLElement | null | undefined diff --git a/packages/ui/container-context/src/ContainerProvider.tsx b/packages/ui/container-context/src/ContainerProvider.tsx new file mode 100644 index 000000000..2b6cc3edd --- /dev/null +++ b/packages/ui/container-context/src/ContainerProvider.tsx @@ -0,0 +1,13 @@ +import React from 'react' +import { ContainerContext } from './ContainerContext' + +export const ContainerProvider: React.FC = ({ children, container }) => { + return {children} +} + +export interface ContainerProviderProps { + /** + * 指定 portal 的容器 + */ + container?: HTMLElement | null +} diff --git a/packages/ui/container-context/src/index.ts b/packages/ui/container-context/src/index.ts new file mode 100644 index 000000000..34ded8b11 --- /dev/null +++ b/packages/ui/container-context/src/index.ts @@ -0,0 +1,4 @@ +export * from './ContainerContext' +export * from './ContainerProvider' + +export { ContainerProvider as default } from './ContainerProvider' diff --git a/packages/ui/container-context/stories/basic.stories.tsx b/packages/ui/container-context/stories/basic.stories.tsx new file mode 100644 index 000000000..28e1f4795 --- /dev/null +++ b/packages/ui/container-context/stories/basic.stories.tsx @@ -0,0 +1,16 @@ +import React, { useContext } from 'react' +import { ContainerContext } from '../src' + +/** + * @title 基础用法 + */ +export const Basic = () => { + const container = useContext(ContainerContext) + + return ( + <> +

Basic

+
{container}
+ + ) +} diff --git a/packages/ui/container-context/stories/index.stories.tsx b/packages/ui/container-context/stories/index.stories.tsx new file mode 100644 index 000000000..3e14b4e19 --- /dev/null +++ b/packages/ui/container-context/stories/index.stories.tsx @@ -0,0 +1,8 @@ +import React from 'react' + +export * from './basic.stories' + +export default { + title: 'Private(暂不对外)/ContainerContext', + decorators: [(story: Function) =>
{story()}
], +} diff --git a/packages/ui/container-context/tsconfig.json b/packages/ui/container-context/tsconfig.json new file mode 100644 index 000000000..f7bbdb2fe --- /dev/null +++ b/packages/ui/container-context/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../../tsconfig.json", + "include": ["./src"] +} diff --git a/packages/ui/drawer/src/Drawer.tsx b/packages/ui/drawer/src/Drawer.tsx index 32c359fc6..067ad1ff9 100644 --- a/packages/ui/drawer/src/Drawer.tsx +++ b/packages/ui/drawer/src/Drawer.tsx @@ -1,7 +1,7 @@ import React, { forwardRef, useCallback, useEffect } from 'react' import { cx, getPrefixCls, getPrefixStyleVar } from '@hi-ui/classname' import { __DEV__ } from '@hi-ui/env' -import { HiBaseHTMLProps } from '@hi-ui/core' +import { HiBaseHTMLProps, useContainerContext } from '@hi-ui/core' import { CSSTransition } from 'react-transition-group' import { Portal } from '@hi-ui/portal' import { useModal, UseModalProps } from '@hi-ui/modal' @@ -33,7 +33,7 @@ export const Drawer = forwardRef( onExited: onExitedProp, title, footer, - container, + container: containerProp, closeIcon = defaultCloseIcon, width, height, @@ -51,6 +51,8 @@ export const Drawer = forwardRef( ) => { const [transitionVisible, transitionVisibleAction] = useToggle(false) const [transitionExited, transitionExitedAction] = useToggle(true) + const globalContainer = useContainerContext() + const container = containerProp ?? globalContainer const { rootProps, getModalProps, getModalWrapperProps } = useModal({ ...rest, diff --git a/packages/ui/drawer/stories/container.stories.tsx b/packages/ui/drawer/stories/container.stories.tsx index e5aa2c79b..1e65305fa 100644 --- a/packages/ui/drawer/stories/container.stories.tsx +++ b/packages/ui/drawer/stories/container.stories.tsx @@ -1,6 +1,7 @@ import React from 'react' import Drawer from '../src' import Button from '@hi-ui/button' +import Provider from '@hi-ui/provider' /** * @title 局部容器抽屉 @@ -31,19 +32,21 @@ export const Container = () => { zIndex: 0, }} > - - setVisible(false)} - > - 我是一段文字,也可以是表单、表格、步骤条等等 - + + + setVisible(false)} + > + 我是一段文字,也可以是表单、表格、步骤条等等 + + ) diff --git a/packages/ui/hiui/src/index.ts b/packages/ui/hiui/src/index.ts index 84635c55c..7a838dc8b 100644 --- a/packages/ui/hiui/src/index.ts +++ b/packages/ui/hiui/src/index.ts @@ -93,6 +93,15 @@ export * from '@hi-ui/locale-context' */ export { default as LocaleContext } from '@hi-ui/locale-context' +/** + * @deprecated Please use the `Provider` instead of it. + */ +export * from '@hi-ui/container-context' +/** + * @deprecated Please use the `Provider` instead of it. + */ +export { default as ContainerContext } from '@hi-ui/container-context' + export * from '@hi-ui/menu' export { default as Menu } from '@hi-ui/menu' diff --git a/packages/ui/loading/src/Loading.tsx b/packages/ui/loading/src/Loading.tsx index bb80c766d..866ab3ee3 100644 --- a/packages/ui/loading/src/Loading.tsx +++ b/packages/ui/loading/src/Loading.tsx @@ -3,7 +3,7 @@ import { CSSTransition } from 'react-transition-group' import { cx, getPrefixCls } from '@hi-ui/classname' import { __DEV__ } from '@hi-ui/env' import { Portal } from '@hi-ui/portal' -import { HiBaseHTMLProps, HiBaseSizeEnum } from '@hi-ui/core' +import { HiBaseHTMLProps, HiBaseSizeEnum, useContainerContext } from '@hi-ui/core' import { useLatestCallback } from '@hi-ui/use-latest' import Spinner from '@hi-ui/spinner' import { useLoading } from './use-loading' @@ -18,7 +18,7 @@ export const Loading = forwardRef( className, children, role = _role, - container, + container: containerProp, content, visible = true, full = false, @@ -38,6 +38,9 @@ export const Loading = forwardRef( ) => { const { internalVisible, setInternalVisible } = useLoading({ visible, delay }) + const globalContainer = useContainerContext() + const container = containerProp ?? globalContainer + useImperativeHandle(innerRef, () => ({ close: () => setInternalVisible(false), })) diff --git a/packages/ui/modal/src/Modal.tsx b/packages/ui/modal/src/Modal.tsx index b37e21984..7ce43fddb 100644 --- a/packages/ui/modal/src/Modal.tsx +++ b/packages/ui/modal/src/Modal.tsx @@ -1,6 +1,6 @@ import React, { useEffect, forwardRef, useCallback, useImperativeHandle } from 'react' import { cx, getPrefixCls } from '@hi-ui/classname' -import { HiBaseHTMLProps, HiBaseSizeEnum, useLocaleContext } from '@hi-ui/core' +import { HiBaseHTMLProps, HiBaseSizeEnum, useLocaleContext, useContainerContext } from '@hi-ui/core' import { __DEV__ } from '@hi-ui/env' import { CSSTransition } from 'react-transition-group' import { Portal } from '@hi-ui/portal' @@ -57,7 +57,7 @@ export const Modal = forwardRef( onClose, onCancel, onConfirm, - container, + container: containerProp, closeIcon = defaultCloseIcon, showMask = true, showHeaderDivider = true, @@ -74,6 +74,9 @@ export const Modal = forwardRef( ) => { const i18n = useLocaleContext() + const globalContainer = useContainerContext() + const container = containerProp ?? globalContainer + const cancelText = isUndef(cancelTextProp) ? i18n.get('modal.cancelText') : cancelTextProp const confirmText = isUndef(confirmTextProp) ? i18n.get('modal.confirmText') : confirmTextProp diff --git a/packages/ui/preview/src/Preview.tsx b/packages/ui/preview/src/Preview.tsx index 8f7bf5ae1..561551fc5 100644 --- a/packages/ui/preview/src/Preview.tsx +++ b/packages/ui/preview/src/Preview.tsx @@ -5,7 +5,7 @@ import { Portal } from '@hi-ui/portal' import { Watermark, WatermarkProps } from '@hi-ui/watermark' import { CSSTransition } from 'react-transition-group' import { useUncontrolledState } from '@hi-ui/use-uncontrolled-state' -import { HiBaseHTMLProps } from '@hi-ui/core' +import { HiBaseHTMLProps, useContainerContext } from '@hi-ui/core' import { useLatestCallback } from '@hi-ui/use-latest' import { ZoomInOutlined, @@ -46,11 +46,16 @@ export const Preview = forwardRef( src, watermarkProps, disabledDownload = false, + container: containerProp, + disabledPortal = false, }, ref ) => { const cls = cx(prefixCls, className) + const globalContainer = useContainerContext() + const container = containerProp ?? globalContainer + const [active, setActive] = useUncontrolledState(defaultCurrent || 0, current, onPreviewChange) const [isMoving, setIsMoving] = useState(false) @@ -199,7 +204,7 @@ export const Preview = forwardRef( ) return ( - +
, 'onError'> { * 当前预览图片索引(受控) */ onPreviewChange?: (current: number) => void + /** + * 指定 portal 的容器 + */ + container?: HTMLElement | null + /** + * 是否禁用 portal + */ + disabledPortal?: boolean } if (__DEV__) { diff --git a/packages/ui/provider/src/Provider.tsx b/packages/ui/provider/src/Provider.tsx index 34c307e14..f76d730c6 100644 --- a/packages/ui/provider/src/Provider.tsx +++ b/packages/ui/provider/src/Provider.tsx @@ -1,6 +1,11 @@ import React, { useEffect } from 'react' import { __DEV__ } from '@hi-ui/env' -import { LocaleProvider, LocaleProviderProps } from '@hi-ui/core' +import { + LocaleProvider, + LocaleProviderProps, + ContainerProvider, + ContainerProviderProps, +} from '@hi-ui/core' import { DesignSystemAccentColorEnum, DesignSystemProps } from './types' import { createSystem, extendsTheme } from './theme' import { getAccentColorTheme } from './accent-color' @@ -13,6 +18,7 @@ export const Provider: React.FC & { extends: ProviderExtendsFunc languages, accentColor, theme, + container, }) => { /** * global css var config @@ -31,13 +37,18 @@ export const Provider: React.FC & { extends: ProviderExtendsFunc }, [accentColor, theme]) return ( - - {children} - + + + {children} + + ) } -export interface ProviderProps extends LocaleProviderProps, ThemeProviderProps {} +export interface ProviderProps + extends LocaleProviderProps, + ContainerProviderProps, + ThemeProviderProps {} interface ThemeProviderProps { /**