diff --git a/packages/components/src/components/popover/__tests__/Popover.test.js b/packages/components/src/components/popover/__tests__/Popover.test.js new file mode 100644 index 0000000000..a2c15ce1ba --- /dev/null +++ b/packages/components/src/components/popover/__tests__/Popover.test.js @@ -0,0 +1,74 @@ +import React from 'react'; +import Popover from '../index'; +import '@gio-design/components/es/components/Tabs/style/index.css'; +import { act } from 'react-dom/test-utils'; +import { mount, render } from 'enzyme'; + +async function waitForComponentToPaint(wrapper, amount = 500) { + await act(async () => new Promise((resolve) => setTimeout(resolve, amount)).then(() => wrapper.update())); +} + +describe('Testing Popover', () => { + const getPopover = () => ( + + Test + + ); + + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('should be stable', () => { + const wrapper = render(getPopover()); + expect(wrapper).toMatchSnapshot(); + }); + + it('should be mount, setProps, unmount with no error', () => { + expect(() => { + const wrapper = mount(getPopover()); + wrapper.setProps({ contentArea: 'content update' }); + wrapper.setProps({ visible: 'true' }); + wrapper.unmount(); + }).not.toThrow(); + }); + + test('prop contentArea', () => { + const wrapper = mount(getPopover()); + wrapper.setProps({ contentArea: 'new text', footerArea: null }); + wrapper.setProps({ trigger: 'click' }); + wrapper.find('span').at(0).simulate('click'); + expect(wrapper.find('.gio-popover-inner').exists('.gio-popover-inner-content')).toBe(true); + expect(wrapper.find('.gio-popover-inner-content').text()).toBe('new text'); + expect(wrapper.find('.gio-popover-inner').exists('.gio-popover-inner-footer')).toBe(false); + }); + + test('prop footerArea', () => { + const wrapper = mount(getPopover()); + wrapper.setProps({ trigger: 'click' }); + wrapper.find('span').at(0).simulate('click'); + wrapper.setProps({ contentArea: 0, footerArea: 'only footer' }); + expect(wrapper.find('.gio-popover-inner').exists('.gio-popover-inner-footer')).toBe(true); + expect(wrapper.find('.gio-popover-inner-footer').text()).toBe('only footer'); + expect(wrapper.find('.gio-popover-inner').exists('.gio-popover-inner-content')).toBe(false); + }); + + it('should be render rightly', () => { + const wrapper = mount(getPopover()); + wrapper.setProps({ trigger: 'click' }); + wrapper.setProps({ placement: 'topLeft' }); + wrapper.setProps({ overlayClassName: 'overlayClassName' }); + wrapper.find('span').at(0).simulate('click'); + expect(wrapper.exists('.gio-popover-inner')).toBe(true); + expect(wrapper.find('.gio-popover-inner').exists('.gio-popover-inner-content')).toBe(true); + expect(wrapper.find('.gio-popover-inner').exists('.gio-popover-inner-footer')).toBe(true); + expect(wrapper.exists('.overlayClassName')).toBe(true); + waitForComponentToPaint(wrapper).then(() => { + expect(wrapper.exists('.gio-popover-placement-topLeft')).toBe(true); + }); + }); +}); diff --git a/packages/components/src/components/popover/__tests__/__snapshots__/Popover.test.js.snap b/packages/components/src/components/popover/__tests__/__snapshots__/Popover.test.js.snap new file mode 100644 index 0000000000..351b88e6e5 --- /dev/null +++ b/packages/components/src/components/popover/__tests__/__snapshots__/Popover.test.js.snap @@ -0,0 +1,48 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Testing Popover should be stable 1`] = ` +initialize { + "0": Object { + "attribs": Object {}, + "children": Array [ + Object { + "data": "Test", + "next": null, + "parent": [Circular], + "prev": null, + "type": "text", + }, + ], + "name": "span", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": null, + "prev": null, + "root": Object { + "attribs": Object {}, + "children": Array [ + [Circular], + ], + "name": "root", + "namespace": "http://www.w3.org/1999/xhtml", + "next": null, + "parent": null, + "prev": null, + "type": "root", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "type": "tag", + "x-attribsNamespace": Object {}, + "x-attribsPrefix": Object {}, + }, + "_root": [Circular], + "length": 1, + "options": Object { + "decodeEntities": true, + "normalizeWhitespace": false, + "withDomLvl1": true, + "xml": false, + }, +} +`; diff --git a/packages/components/src/components/popover/index.tsx b/packages/components/src/components/popover/index.tsx new file mode 100644 index 0000000000..fa360d0aa2 --- /dev/null +++ b/packages/components/src/components/popover/index.tsx @@ -0,0 +1,24 @@ +import React, { useContext } from 'react'; +import Tooltip from '../tooltip'; +import { PopoverProps } from './interface'; +import { ConfigContext } from '../config-provider'; + +const Popover: React.FC = (props: PopoverProps) => { + const { children, contentArea, footerArea, prefixCls: customizePrefixCls, ...rest } = props; + const { getPrefixCls } = useContext(ConfigContext); + const prefixCls = getPrefixCls('popover', customizePrefixCls); + + const popoverOverlay = () => ( + <> + {contentArea &&
{contentArea}
} + {footerArea &&
{footerArea}
} + + ); + return ( + + {children} + + ); +}; + +export default Popover; diff --git a/packages/components/src/components/popover/interface.ts b/packages/components/src/components/popover/interface.ts new file mode 100644 index 0000000000..f9dd19a9ab --- /dev/null +++ b/packages/components/src/components/popover/interface.ts @@ -0,0 +1,7 @@ +import { TooltipProps } from '../tooltip/interface'; + +export type ReactRender = () => React.ReactNode; +export interface PopoverProps extends Omit { + contentArea: React.ReactNode | ReactRender; + footerArea?: React.ReactNode | ReactRender; +} diff --git a/packages/components/src/components/popover/style/index.less b/packages/components/src/components/popover/style/index.less new file mode 100644 index 0000000000..3ee2eceba5 --- /dev/null +++ b/packages/components/src/components/popover/style/index.less @@ -0,0 +1,64 @@ +@import '../../../stylesheet/theme.less'; +@import '../../../stylesheet/mixin/trigger.less'; +@import '~@gio-design/tokens/dist/variables.less'; + +@popover-prefix-cls: ~'@{component-prefix}-popover'; +@popover-arrow-width: 12px; +@distance: 6px; +@popover-offset: 20px; +@popover-duration: 10ms; + +.@{popover-prefix-cls}{ + margin: auto; + position: absolute; + z-index: 100; + + &-hidden { + display: none; + } + + &-content { + position: relative; + } + + &-inner { + box-shadow: @shadow-popover; + border-radius: 4px; + background-color: @color-background-popover; + display: block; + overflow: hidden; + &-content{ + margin: 20px; + position: relative; + overflow: hidden; + } + &-footer { + margin: -4px 20px 16px; + position: relative; + overflow: hidden; + } + } + + &-arrow { + position: absolute; + display: block; + pointer-events: none; + height: 12px; + width: 12px; + &-content { + position: absolute; + margin: auto; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 0px; + height: 0px; + border: @popover-arrow-width/2 solid; + pointer-events: auto; + } + } + .trigger-placement(@popover-prefix-cls, @color-background-popover, @popover-arrow-width, @distance, @popover-offset); +} + +.trigger-transition(@popover-prefix-cls, @popover-duration); \ No newline at end of file diff --git a/packages/components/src/components/tooltip/index.tsx b/packages/components/src/components/tooltip/index.tsx index 57ff11f61a..bea191696d 100644 --- a/packages/components/src/components/tooltip/index.tsx +++ b/packages/components/src/components/tooltip/index.tsx @@ -3,6 +3,7 @@ import RcTooltip from 'rc-tooltip'; import { TooltipProps } from './interface'; import { ConfigContext } from '../config-provider'; import Link from '../link'; +import getPlacements from './placements'; const Tooltip = (props: TooltipProps) => { const { @@ -13,12 +14,13 @@ const Tooltip = (props: TooltipProps) => { prefixCls: customizePrefixCls, overlay, children, + arrowPointAtCenter, ...rest } = props; const { getPrefixCls } = useContext(ConfigContext); const prefixCls = getPrefixCls('tooltip', customizePrefixCls); - const defaultOverlay = () => ( + const tooltipOverlay = () => ( <> {title} {tooltipLink?.link && ( @@ -29,7 +31,14 @@ const Tooltip = (props: TooltipProps) => { ); - const getOverlay = () => overlay || defaultOverlay(); + const setCursor = (child: React.ReactElement) => { + if (trigger === 'click' || (Array.isArray(trigger) && trigger.includes('click'))) { + return React.cloneElement(child, { style: { cursor: 'pointer' } }); + } + return child; + }; + + const getOverlay = () => overlay || tooltipOverlay(); return ( { transitionName='spread-transition' arrowContent={} overlay={getOverlay()} + builtinPlacements={getPlacements({ arrowPointAtCenter })} {...rest} > - {children} + {setCursor(children)} ); }; diff --git a/packages/components/src/components/tooltip/interface.ts b/packages/components/src/components/tooltip/interface.ts index 40f15d2902..e7424f937c 100644 --- a/packages/components/src/components/tooltip/interface.ts +++ b/packages/components/src/components/tooltip/interface.ts @@ -8,6 +8,6 @@ export interface TooltipLink { export interface TooltipProps extends Partial { title?: React.ReactNode | ReactRender; tooltipLink?: TooltipLink; - children?: React.ReactElement; - placement?: string; + arrowPointAtCenter?: boolean; + children: React.ReactElement; } diff --git a/packages/components/src/components/tooltip/placements.ts b/packages/components/src/components/tooltip/placements.ts new file mode 100644 index 0000000000..00f53b738e --- /dev/null +++ b/packages/components/src/components/tooltip/placements.ts @@ -0,0 +1,112 @@ +import { placements } from 'rc-tooltip/lib/placements'; +import { BuildInPlacements } from 'rc-trigger'; + +const autoAdjustOverflowEnabled = { + adjustX: 1, + adjustY: 1, +}; + +const autoAdjustOverflowDisabled = { + adjustX: 0, + adjustY: 0, +}; + +const targetOffset = [0, 0]; + +export interface AdjustOverflow { + adjustX?: 0 | 1; + adjustY?: 0 | 1; +} + +export interface PlacementsConfig { + arrowWidth?: number; + horizontalArrowShift?: number; + verticalArrowShift?: number; + arrowPointAtCenter?: boolean; + autoAdjustOverflow?: boolean | AdjustOverflow; +} + +export function getOverflowOptions(autoAdjustOverflow?: boolean | AdjustOverflow) { + if (typeof autoAdjustOverflow === 'boolean') { + return autoAdjustOverflow ? autoAdjustOverflowEnabled : autoAdjustOverflowDisabled; + } + return { + ...autoAdjustOverflowDisabled, + ...autoAdjustOverflow, + }; +} + +export default function getPlacements(config: PlacementsConfig) { + const { + arrowWidth = 6, + horizontalArrowShift = 20, + verticalArrowShift = 20, + autoAdjustOverflow = true, + arrowPointAtCenter, + } = config; + const placementMap: BuildInPlacements = { + left: { + points: ['cr', 'cl'], + offset: [-4, 0], + }, + right: { + points: ['cl', 'cr'], + offset: [4, 0], + }, + top: { + points: ['bc', 'tc'], + offset: [0, -4], + }, + bottom: { + points: ['tc', 'bc'], + offset: [0, 4], + }, + topLeft: { + points: ['bl', 'tc'], + offset: [-(horizontalArrowShift + arrowWidth), -4], + }, + leftTop: { + points: ['tr', 'cl'], + offset: [-4, -(verticalArrowShift + arrowWidth)], + }, + topRight: { + points: ['br', 'tc'], + offset: [horizontalArrowShift + arrowWidth, -4], + }, + rightTop: { + points: ['tl', 'cr'], + offset: [4, -(verticalArrowShift + arrowWidth)], + }, + bottomRight: { + points: ['tr', 'bc'], + offset: [horizontalArrowShift + arrowWidth, 4], + }, + rightBottom: { + points: ['bl', 'cr'], + offset: [4, verticalArrowShift + arrowWidth], + }, + bottomLeft: { + points: ['tl', 'bc'], + offset: [-(horizontalArrowShift + arrowWidth), 4], + }, + leftBottom: { + points: ['br', 'cl'], + offset: [-4, verticalArrowShift + arrowWidth], + }, + }; + Object.keys(placementMap).forEach((key) => { + placementMap[key] = arrowPointAtCenter + ? { + ...placementMap[key], + overflow: getOverflowOptions(autoAdjustOverflow), + targetOffset, + } + : { + ...placements[key], + overflow: getOverflowOptions(autoAdjustOverflow), + }; + + placementMap[key].ignoreShake = true; + }); + return placementMap; +} diff --git a/packages/components/src/components/tooltip/style/index.less b/packages/components/src/components/tooltip/style/index.less index b201fd91f8..9a096c775b 100644 --- a/packages/components/src/components/tooltip/style/index.less +++ b/packages/components/src/components/tooltip/style/index.less @@ -1,11 +1,12 @@ @import '../../../stylesheet/theme.less'; @import '../../../stylesheet/mixin/trigger.less'; +@import '~@gio-design/tokens/dist/variables.less'; @tooltip-prefix-cls: ~'@{component-prefix}-tooltip'; -@tooltip-bg-color: rgba(36, 46, 89, 0.96); @tooltip-distance: 6px; @tooltip-arrow-width: 12px; @tooltip-arrow-offset: 14px; +@tooltip-duration: 0.5s; .@{tooltip-prefix-cls}{ max-width: 500px; @@ -17,12 +18,11 @@ } &-content { - display: inline-block; position: relative; } &-inner { - color: #FFFFFF; + color: @color-text-tooltip; text-align: left; text-decoration: none; word-wrap: break-word; @@ -30,7 +30,7 @@ letter-spacing: 0; line-height: 22px; border-radius: 4px; - background-color: @tooltip-bg-color; + background-color: @color-background-tooltip; padding: 8px 16px; display: inline-block; min-width: 40px; @@ -42,7 +42,7 @@ } } .gio-link{ - color: #FFFFFF; + color: @color-text-tooltip; } } @@ -65,7 +65,7 @@ pointer-events: auto; } } - .trigger-placement(@tooltip-prefix-cls, @tooltip-bg-color, @tooltip-arrow-width, @tooltip-distance, @tooltip-arrow-offset); + .trigger-placement(@tooltip-prefix-cls, @color-background-tooltip, @tooltip-arrow-width, @tooltip-distance, @tooltip-arrow-offset); } -.trigger-transition(@tooltip-prefix-cls); \ No newline at end of file +.trigger-transition(@tooltip-prefix-cls, @tooltip-duration); \ No newline at end of file diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 0d924c4748..885e11ab21 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -6,3 +6,4 @@ export { default as Link } from './components/link'; export { default as Avatar, AvatarGroup } from './components/avatar'; export { default as Tabs, TabPane } from './components/tabs'; export { default as Tooltip } from './components/tooltip'; +export { default as Popover } from './components/popover'; diff --git a/packages/components/src/stylesheet/mixin/trigger.less b/packages/components/src/stylesheet/mixin/trigger.less index 9f00de0da0..3ee665cbf8 100644 --- a/packages/components/src/stylesheet/mixin/trigger.less +++ b/packages/components/src/stylesheet/mixin/trigger.less @@ -53,10 +53,15 @@ left: 50%; transform: translateX(-50%); } + &-placement-left &-arrow, + &-placement-right &-arrow { + top: 50%; + transform: translateY(-50%); + } &-placement-topLeft &-arrow, &-placement-bottomLeft &-arrow { - left: @arrow-offset; + left: @arrow-offset; } &-placement-topRight &-arrow, @@ -70,17 +75,15 @@ } &-placement-leftTop &-arrow, - &-placement-rightTop &-arrow, - &-placement-left &-arrow, - &-placement-right &-arrow { + &-placement-rightTop &-arrow { top: @arrow-offset; } } -.trigger-transition(@prefix-cls){ +.trigger-transition(@prefix-cls, @duration){ .spread-transition { &-enter, &-appear { - animation-duration: 0.5s; + animation-duration: @duration; animation-fill-mode: both; animation-play-state: paused; opacity: 0; @@ -110,7 +113,7 @@ } } &-leave{ - animation-duration: 0.5s; + animation-duration: @duration; animation-fill-mode: both; animation-play-state: paused; &&-active{ diff --git a/packages/tokens/config.js b/packages/tokens/config.js index 01f3790156..9277d179f6 100644 --- a/packages/tokens/config.js +++ b/packages/tokens/config.js @@ -8,4 +8,24 @@ StyleDictionary.registerFormat({ formatter: typingsES6Template, }); +StyleDictionary.registerTransform({ + name: 'shadow/complex', + type: 'value', + matcher: (prop) => prop.attributes.type === 'shadow', + transformer: (prop) => prop.original.value, +}); + +StyleDictionary.registerTransformGroup({ + name: 'less', + transforms: [ + 'attribute/cti', + 'name/cti/kebab', + 'time/seconds', + 'content/icon', + 'size/rem', + 'color/hex8', + 'shadow/complex', + ], +}); + StyleDictionary.buildAllPlatforms(); diff --git a/packages/tokens/properties/color/background.json b/packages/tokens/properties/color/background.json index 02e8a21b02..a7d9bc59b0 100644 --- a/packages/tokens/properties/color/background.json +++ b/packages/tokens/properties/color/background.json @@ -2,9 +2,19 @@ "color": { "background": { "avatar": { - "normal": "{palette.gray.3.value}", - "hover": "{palette.blue.7.value}" + "normal": { + "value": "{palette.gray.3.value}" + }, + "hover": { + "value": "{palette.blue.7.value}" + } + }, + "tooltip": { + "value": "rgba(36, 46, 89, 0.96)" + }, + "popover": { + "value": "{palette.white.value}" } } } -} \ No newline at end of file +} diff --git a/packages/tokens/properties/color/text.json b/packages/tokens/properties/color/text.json index 78ce55472b..ce1c67f170 100644 --- a/packages/tokens/properties/color/text.json +++ b/packages/tokens/properties/color/text.json @@ -19,7 +19,10 @@ "click": { "value": "{palette.dark.1.value}" } + }, + "tooltip": { + "value": "{palette.white.value}" } } } -} \ No newline at end of file +} diff --git a/packages/tokens/properties/shadow.json b/packages/tokens/properties/shadow.json new file mode 100644 index 0000000000..7972c13095 --- /dev/null +++ b/packages/tokens/properties/shadow.json @@ -0,0 +1,7 @@ +{ + "shadow": { + "popover": { + "value": "0 2px 14px 0 rgba(223, 226, 237, 0.8)" + } + } +} diff --git a/packages/website/src/components/basic/breadcrumb/index.zh-CN.md b/packages/website/src/components/basic/breadcrumb/index.zh-CN.md index d2da0d8dbe..c9219eddba 100644 --- a/packages/website/src/components/basic/breadcrumb/index.zh-CN.md +++ b/packages/website/src/components/basic/breadcrumb/index.zh-CN.md @@ -5,6 +5,7 @@ nav: title: 组件 group: title: 基础组件 + order: 1 --- # Breadcrumb 面包屑 diff --git a/packages/website/src/components/basic/checkbox/index.zh-CN.md b/packages/website/src/components/basic/checkbox/index.zh-CN.md index 0e3b0147a6..1cbe50962d 100644 --- a/packages/website/src/components/basic/checkbox/index.zh-CN.md +++ b/packages/website/src/components/basic/checkbox/index.zh-CN.md @@ -5,6 +5,7 @@ nav: title: 组件 group: title: 基础组件 + order: 1 --- # Checkbox 多选框 diff --git a/packages/website/src/components/basic/link/index.zh-CN.md b/packages/website/src/components/basic/link/index.zh-CN.md index b53a3d080c..6048411740 100644 --- a/packages/website/src/components/basic/link/index.zh-CN.md +++ b/packages/website/src/components/basic/link/index.zh-CN.md @@ -5,6 +5,7 @@ nav: title: 组件 group: title: 基础组件 + order: 1 --- # Link 链接 diff --git a/packages/website/src/components/basic/radio/index.zh-CN.md b/packages/website/src/components/basic/radio/index.zh-CN.md index ee1fcead56..1c7ac17df8 100644 --- a/packages/website/src/components/basic/radio/index.zh-CN.md +++ b/packages/website/src/components/basic/radio/index.zh-CN.md @@ -5,6 +5,7 @@ nav: title: 组件 group: title: 基础组件 + order: 1 --- # Radio 单选框 diff --git a/packages/website/src/components/basic/tabs/index.zh-CN.md b/packages/website/src/components/basic/tabs/index.zh-CN.md index 565f8f8979..0893c0ee0f 100644 --- a/packages/website/src/components/basic/tabs/index.zh-CN.md +++ b/packages/website/src/components/basic/tabs/index.zh-CN.md @@ -5,6 +5,7 @@ nav: title: 组件 group: title: 基础组件 + order: 1 --- # Tabs 标签页 diff --git a/packages/website/src/components/basic/toast/index.zh-CN.md b/packages/website/src/components/basic/toast/index.zh-CN.md index df96d229d7..680649d1ec 100644 --- a/packages/website/src/components/basic/toast/index.zh-CN.md +++ b/packages/website/src/components/basic/toast/index.zh-CN.md @@ -5,6 +5,7 @@ nav: title: 组件 group: title: 基础组件 + order: 1 --- # Toast 全局提示 diff --git a/packages/website/src/components/basic/tooltip/index.zh-CN.md b/packages/website/src/components/basic/tooltip/index.zh-CN.md index 7544b032ca..cdb4e0515d 100644 --- a/packages/website/src/components/basic/tooltip/index.zh-CN.md +++ b/packages/website/src/components/basic/tooltip/index.zh-CN.md @@ -5,6 +5,7 @@ nav: title: 组件 group: title: 基础组件 + order: 1 --- # Tooltip 文字提示 @@ -21,16 +22,22 @@ group: ## 参数说明 -| 参数 | 说明 | 类型 | 默认值 | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | --------------------- | -| **title** | 提示文字 | string \| ReactNode \| () => ReactNode | | -| **tooltipLink** | 设置头像的链接以及链接的文字 | { name?: string, link: string } | | -| **getPopupContainer** | 浮层渲染父节点,默认渲染到 body 上 | function(triggerNode) | `() => document.body` | -| **overlayClassName** | 添加 className | string | `''` | -| **placement** | 气泡框位置, 可选 `top` `left` `right` `bottom` `topLeft` `topRight` `bottomLeft` `bottomRight` `leftTop` `leftBottom` `rightTop` `rightBottom` | string | `'top'` | -| **trigger** | 触发行为,可选 hover,focus,click,contextMenu | string\|string[] | `hover` | -| **visible** | 用于手动控制浮层显隐 | boolean | `false` | -| **onVisibleChange** | 显示隐藏的回调 | (visible) => void | | -| **destroyTooltipOnHide** | 关闭后是否销毁 Tooltip,当 keepParent 为 false 时销毁父容器 | boolean\|{ keepParent?: boolean } | `false` | +| 参数 | 说明 | 类型 | 默认值 | +| --------------- | ---------------------------- | -------------------------------------- | ------ | +| **title** | 提示文字 | string \| ReactNode \| () => ReactNode | | +| **tooltipLink** | 设置头像的链接以及链接的文字 | { name?: string, link: string } | + +以下 API 为 Tooltip、Popconfirm、Popover 共享的 API。 + +| 参数 | 说明 | 类型 | 默认值 | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | --------------------- | +| **getPopupContainer** | 浮层渲染父节点,默认渲染到 body 上 | function(triggerNode) | `() => document.body` | +| **overlayClassName** | 添加 className | string | `''` | +| **placement** | 气泡框位置, 可选 `top` `left` `right` `bottom` `topLeft` `topRight` `bottomLeft` `bottomRight` `leftTop` `leftBottom` `rightTop` `rightBottom` | string | `'top'` | +| **trigger** | 触发行为,可选 hover,focus,click,contextMenu | string\|string[] | `hover` | +| **visible** | 用于手动控制浮层显隐 | boolean | `false` | +| **onVisibleChange** | 显示隐藏的回调 | (visible) => void | | +| **destroyTooltipOnHide** | 关闭后是否销毁 Tooltip,当 keepParent 为 false 时销毁父容器 | boolean\|{ keepParent?: boolean } | `false` | +| **arrowPointAtCenter** | 箭头是否指向目标元素中心 | boolean | `false` | 更多参数请参考 [rc-tooltip](https://github.com/react-component/tooltip) diff --git a/packages/website/src/components/basic/avatar/demo/Avatar.png b/packages/website/src/components/functional/avatar/demo/Avatar.png similarity index 100% rename from packages/website/src/components/basic/avatar/demo/Avatar.png rename to packages/website/src/components/functional/avatar/demo/Avatar.png diff --git a/packages/website/src/components/basic/avatar/demo/base.tsx b/packages/website/src/components/functional/avatar/demo/base.tsx similarity index 100% rename from packages/website/src/components/basic/avatar/demo/base.tsx rename to packages/website/src/components/functional/avatar/demo/base.tsx diff --git a/packages/website/src/components/basic/avatar/demo/group.tsx b/packages/website/src/components/functional/avatar/demo/group.tsx similarity index 100% rename from packages/website/src/components/basic/avatar/demo/group.tsx rename to packages/website/src/components/functional/avatar/demo/group.tsx diff --git a/packages/website/src/components/basic/avatar/demo/hover.tsx b/packages/website/src/components/functional/avatar/demo/hover.tsx similarity index 100% rename from packages/website/src/components/basic/avatar/demo/hover.tsx rename to packages/website/src/components/functional/avatar/demo/hover.tsx diff --git a/packages/website/src/components/basic/avatar/demo/index.less b/packages/website/src/components/functional/avatar/demo/index.less similarity index 100% rename from packages/website/src/components/basic/avatar/demo/index.less rename to packages/website/src/components/functional/avatar/demo/index.less diff --git a/packages/website/src/components/basic/avatar/demo/size.tsx b/packages/website/src/components/functional/avatar/demo/size.tsx similarity index 100% rename from packages/website/src/components/basic/avatar/demo/size.tsx rename to packages/website/src/components/functional/avatar/demo/size.tsx diff --git a/packages/website/src/components/basic/avatar/index.zh-CN.md b/packages/website/src/components/functional/avatar/index.zh-CN.md similarity index 98% rename from packages/website/src/components/basic/avatar/index.zh-CN.md rename to packages/website/src/components/functional/avatar/index.zh-CN.md index 95bf452fc0..df5dd3cfce 100644 --- a/packages/website/src/components/basic/avatar/index.zh-CN.md +++ b/packages/website/src/components/functional/avatar/index.zh-CN.md @@ -4,7 +4,8 @@ nav: order: 2 title: 组件 group: - title: 基础组件 + title: 功能组件 + order: 2 --- # Avatar 头像 diff --git a/packages/website/src/components/functional/popover/demo/2vcode.png b/packages/website/src/components/functional/popover/demo/2vcode.png new file mode 100644 index 0000000000..3cc7dedae4 Binary files /dev/null and b/packages/website/src/components/functional/popover/demo/2vcode.png differ diff --git a/packages/website/src/components/functional/popover/demo/arrow.tsx b/packages/website/src/components/functional/popover/demo/arrow.tsx new file mode 100644 index 0000000000..b9c3522bd1 --- /dev/null +++ b/packages/website/src/components/functional/popover/demo/arrow.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { Popover } from '@gio-design/components'; +import '@gio-design/components/es/components/popover/style/index.css'; +import './index.less'; +import image from './2vcode.png'; + +export default () => ( + <> + } + footerArea={下载二维码} + arrowPointAtCenter={true} + > + + Arrow points to center / 箭头指向中心 + + + } + footerArea={下载二维码} + > + Align edge / 边缘对齐 + + +); diff --git a/packages/website/src/components/functional/popover/demo/base.tsx b/packages/website/src/components/functional/popover/demo/base.tsx new file mode 100644 index 0000000000..ce14b96bc4 --- /dev/null +++ b/packages/website/src/components/functional/popover/demo/base.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import { Popover, Checkbox, CheckboxGroup, Link } from '@gio-design/components'; +import '@gio-design/components/es/components/popover/style/index.css'; +import './index.less'; + +export default () => ( + <> + +

广告阶段

+ + 点击 + 到站访问 + 到站访问率 + +

+ 用户量 +

+ + 用户总量 + 新增 + 回访 + + + } + > + hover me +
+ + +

+ *此链接用于统计渠道点击数据,请用此链接替换点击跳转地址。 +

+ + } + footerArea={复制链接} + > + + hover me + +
+ +); diff --git a/packages/website/src/components/functional/popover/demo/click.tsx b/packages/website/src/components/functional/popover/demo/click.tsx new file mode 100644 index 0000000000..4675bdfb93 --- /dev/null +++ b/packages/website/src/components/functional/popover/demo/click.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { Popover, Checkbox, CheckboxGroup, Link } from '@gio-design/components'; +import '@gio-design/components/es/components/popover/style/index.css'; +import './index.less'; +import image from './2vcode.png'; + +export default () => ( + <> + } + footerArea={下载二维码} + trigger="click" + > + click me + + + +

+ *此链接用于统计渠道点击数据,请用此链接替换点击跳转地址。 +

+ + } + footerArea={复制链接} + trigger="click" + > + click me +
+ +); diff --git a/packages/website/src/components/functional/popover/demo/index.less b/packages/website/src/components/functional/popover/demo/index.less new file mode 100644 index 0000000000..707cd14fd5 --- /dev/null +++ b/packages/website/src/components/functional/popover/demo/index.less @@ -0,0 +1,95 @@ +.gio-popover-inner { + &-content { + .displayInput { + display: block; + height: 30px; + width: 220px; + border: 1px solid #dcdfed; + border-radius: 4px; + background-color: #ffffff; + &:focus { + outline: none; + } + } + .title { + color: #313e75; + font-size: 14px; + } + .desc { + color: #a3adc8; + font-size: 12px; + width: 220px; + margin-top: 8px; + margin-bottom: 0px; + } + } + &-footer { + .button { + height: 30px; + border-radius: 4px; + background-color: #3867f4; + color: #ffffff; + font-size: 14px; + letter-spacing: 0; + line-height: 22px; + display: inline-block; + padding: 4px 16px; + } + .centerButton { + .button; + width: 108px; + margin: 0 auto; + display: block; + } + .rightButton { + .button; + float: right; + } + } +} + +@button-width: 100px; +.popoverSpan { + display: inline-block; + padding: 5px 8px; + border: 1px solid #adadad; + text-align: center; + margin: 10px; + width: @button-width; +} + +.popoverSpanInLine { + display: inline-block; + padding: 5px 8px; + border: 1px solid #adadad; + text-align: center; + margin: 10px; +} + +.popover-top { + margin-left: @button-width; + & > .tooltipSpan { + margin: 0 10px; + } +} + +.popover-left { + float: left; + width: @button-width; + & > .tooltipSpan { + margin: 10px 0; + } +} +.popover-buttom { + margin-left: @button-width; + & > .tooltipSpan { + margin: 0 10px; + } +} +.popover-right { + width: @button-width; + margin-left: 450px; + & > .tooltipSpan { + margin: 10px 0; + } +} diff --git a/packages/website/src/components/functional/popover/demo/placement.tsx b/packages/website/src/components/functional/popover/demo/placement.tsx new file mode 100644 index 0000000000..b3a0b6de5b --- /dev/null +++ b/packages/website/src/components/functional/popover/demo/placement.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { Popover } from '@gio-design/components'; +import '@gio-design/components/es/components/popover/style/index.css'; +import './index.less'; +import image from './2vcode.png'; + +const props = { + contentArea: , + footerArea: 下载二维码, + trigger: 'click', + arrowPointAtCenter: true, +}; + +export default () => ( + <> +
+ + TopLeft + + + Top + + + TopRight + +
+ +
+ + LeftTop + + + Left + + + LeftBottom + +
+
+ + RightTop + + + Right + + + RightBottom + +
+
+ + BottomLeft + + + Bottom + + + BottomRight + +
+ +); diff --git a/packages/website/src/components/functional/popover/index.zh-CN.md b/packages/website/src/components/functional/popover/index.zh-CN.md new file mode 100644 index 0000000000..e5a198a085 --- /dev/null +++ b/packages/website/src/components/functional/popover/index.zh-CN.md @@ -0,0 +1,32 @@ +--- +title: Popover 气泡卡片 +nav: + order: 2 + title: 组件 +group: + title: 功能组件 + order: 2 +--- + +# Popover 气泡卡片 + +鼠标悬浮或者点击后弹出气泡式的卡片浮层。和 Tooltip 的区别是,用户可以对浮层上的元素进行操作,因此它可以承载更复杂的内容,比如链接或按钮等。 + +## 代码演示 + + + + + + + + + +## 参数说明 + +| 参数 | 说明 | 类型 | 默认值 | +| --------------- | ------------ | ---------------------------- | ------ | +| **contentArea** | 卡片内容区域 | ReactNode \| () => ReactNode | | +| **footerArea** | 卡片按钮区域 | ReactNode \| () => ReactNode | | + +更多参数参考[Tooltip](/components/basic/tooltip)