Balloon 气泡提示

如果项目中使用的是 0.x 版本的基础组件(@icedesign/base, @ali/ice, @alife/next),请在左侧导航顶部切换组件版本。

安装方法

  1. 在命令行中执行以下命令npm install @alifd/next@latest -S

开发指南

气泡组件

何时使用

  • 当用户与被说明对象(文字,图片,输入框等)发生交互行为的action开始时, 即刻跟随动作出现一种辅助或帮助的提示信息。

  • 其中Balloon.Tooltip是简化版本,主要用于hover时显示简单文案。

使用注意

  • 对于trigger是自定义的React Component的情况,自定义的React Component 需要透传onMouseEnter/onMouseLeave/onClick 事件。

  • 若要使用无障碍的气泡提示,请传入id。推荐简单提示使用<Tooltip>、复杂交互使用<Balloon triggerType="click"> 。 triggerType="focus"作为辅助状态用于组件内部,请用户不要直接使用此值。

API

Balloon

参数说明类型默认值
children浮层的内容any-
type样式类型可选值:'normal', 'primary'Enum'normal'
visible弹层当前显示的状态Boolean-
defaultVisible弹层默认显示的状态Booleanfalse
onVisibleChange弹层在显示和隐藏触发的事件签名:Function(visible: Boolean, type: String) => void参数:visible: {Boolean} 弹层是否隐藏和显示type: {String} 触发弹层显示或隐藏的来源, closeClick 表示由自带的关闭按钮触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发Functionfunc.noop
alignEdge弹出层对齐方式Booleanfalse
closable是否显示关闭按钮Booleantrue
align弹出层位置可选值:'t'(上)'r'(右)'b'(下)'l'(左)'tl'(上左)'tr'(上右)'bl'(下左)'br'(下右)'lt'(左上)'lb'(左下)'rt'(右上)'rb'(右下 及其 两两组合)Enum'b'
offset弹层相对于trigger的定位的微调, 接收数组hoz, ver, 表示弹层在 left / top 上的增量e.g. 100, 100 表示往右(RTL 模式下是往左) 、下分布偏移100pxArray0, 0
trigger触发元素any<span />
triggerType触发行为鼠标悬浮, 鼠标点击('hover','click')或者它们组成的数组,如 'hover', 'click', 强烈不建议使用'focus',若弹窗内容有复杂交互请使用clickString/Array'hover'
onClose任何visible为false时会触发的事件签名:Function() => voidFunctionfunc.noop
needAdjust是否进行自动位置调整Booleanfalse
delay弹层在触发以后的延时显示, 单位毫秒 msNumber-
afterClose浮层关闭后触发的事件, 如果有动画,则在动画结束后触发签名:Function() => voidFunctionfunc.noop
shouldUpdatePosition强制更新定位信息Boolean-
autoFocus弹层出现后是否自动focus到内部第一个元素Booleantrue
safeNode安全节点:对于triggetType为click的浮层,会在点击除了浮层外的其它区域时关闭浮层.safeNode用于添加不触发关闭的节点, 值可以是dom节点的id或者是节点的dom对象Stringundefined
safeId用来指定safeNode节点的id,和safeNode配合使用Stringnull
animation配置动画的播放方式Object/Boolean{ in: 'zoomIn', out: 'zoomOut', }
cache弹层的dom节点关闭时是否删除Booleanfalse
popupContainer指定浮层渲染的父节点, 可以为节点id的字符串,也可以返回节点的函数。String/Function-
popupStyle弹层组件style,透传给PopupObject{}
popupClassName弹层组件className,透传给PopupString''
popupProps弹层组件属性,透传给PopupObject{}
followTrigger是否跟随滚动Boolean-
id弹层id, 传入值才会支持无障碍String-

Balloon.Tooltip

参数说明类型默认值
childrentooltip的内容any-
align弹出层位置可选值:'t'(上)'r'(右)'b'(下)'l'(左)'tl'(上左)'tr'(上右)'bl'(下左)'br'(下右)'lt'(左上)'lb'(左下)'rt'(右上)'rb'(右下 及其 两两组合)Enum'b'
trigger触发元素any<span />
triggerType触发行为鼠标悬浮, 鼠标点击('hover', 'click')或者它们组成的数组,如 'hover', 'click', 强烈不建议使用'focus',若有复杂交互,推荐使用triggerType为click的Balloon组件String/Array'hover'
popupStyle弹层组件style,透传给PopupObject-
popupClassName弹层组件className,透传给PopupString-
popupProps弹层组件属性,透传给PopupObject-
pure是否pure renderBoolean-
popupContainer指定浮层渲染的父节点, 可以为节点id的字符串,也可以返回节点的函数。String/Function-
followTrigger是否跟随滚动Boolean-
id弹层id, 传入值才会支持无障碍String-

已知问题

  • 对于 disabled 的元素,onMouseLeave 事件在chrome下无法触发,此为chrome的bug,暂时无法绕过。

ARIA and KeyBoard

按键说明
SPACEtriggerType=‘click’时,点击会弹出提示
EntertriggerType=‘click’时,点击会弹出提示

代码示例

基本

最简单的用法。

Balloon 气泡提示 - 图1

查看源码在线预览

  1. import { Button, Balloon } from '@alifd/next';
  2. const defaultTrigger = <Button className="btrigger" style={{margin: '5px'}}>default style</Button>;
  3. const disabledTrigger = <Button disabled className="btrigger" style={{margin: '5px'}}>default style</Button>;
  4. const primary = <Button className="btrigger" style={{margin: '5px'}}>primary style</Button>;
  5. const Demo = () => (
  6. <div className="container">
  7. <Balloon trigger={defaultTrigger} closable={false}>
  8. default
  9. </Balloon>
  10. <Balloon type="primary" trigger={primary} triggerType="click">
  11. primary
  12. </Balloon>
  13. <Balloon trigger={disabledTrigger} closable={false}>
  14. disabeled default
  15. </Balloon>
  16. </div>
  17. );
  18. ReactDOM.render(<Demo />, mountNode);

三种触发方式

鼠标移入、聚集、点击。

Balloon 气泡提示 - 图2

查看源码在线预览

  1. import { Button, Balloon, Input } from '@alifd/next';
  2. const content = (<div><p>content</p></div>);
  3. const MoveTarget = <Button style={{margin: '5px'}}>hover</Button>;
  4. const ClickTarget = <Button style={{margin: '5px'}}>click</Button>;
  5. const FocusTarget = <Button style={{margin: '5px'}}>focus</Button>;
  6. const HoverInputTarget = <Input placeholder="hover" style={{marginRight: '20px'}}/>;
  7. const ClickInputTarget = <Input placeholder="click" style={{marginRight: '20px'}}/>;
  8. const FocusInputTarget = <Input placeholder="focus" />;
  9. const App = () => (
  10. <div>
  11. <Balloon trigger={MoveTarget} triggerType="hover">
  12. {content}
  13. </Balloon>
  14. <Balloon trigger={ClickTarget} triggerType="click">
  15. {content}
  16. </Balloon>
  17. <Balloon trigger={FocusTarget} triggerType="focus">
  18. {content}
  19. </Balloon>
  20. <br/>
  21. <br/>
  22. <Balloon trigger={HoverInputTarget} triggerType="hover">
  23. {content}
  24. </Balloon>
  25. <Balloon trigger={ClickInputTarget} triggerType="click">
  26. {content}
  27. </Balloon>
  28. <Balloon trigger={FocusInputTarget} triggerType="focus">
  29. {content}
  30. </Balloon>
  31. </div>
  32. );
  33. ReactDOM.render(<App />, mountNode);

边缘对齐设置

位置有十二个方向。

Balloon 气泡提示 - 图3

查看源码在线预览

  1. import { Button, Balloon } from '@alifd/next';
  2. const top = <Button id="top" style={{margin: '5px'}} className="btrigger">top</Button>;
  3. const right = <Button id="right" style={{margin: '5px'}} className="btrigger">right</Button>;
  4. const bottom = <Button id="bottom" style={{margin: '5px'}} className="btrigger">bottom</Button>;
  5. const left = <Button id="left" style={{margin: '5px'}} className="btrigger">left</Button>;
  6. const topLeft = <Button id="topLeft" style={{margin: '5px'}} className="btrigger">top left</Button>;
  7. const topRight = <Button id="topRight" style={{margin: '5px'}} className="btrigger">top right</Button>;
  8. const rightTop = <Button id="rightTop" style={{margin: '5px'}} className="btrigger">right top</Button>;
  9. const rightBottom = <Button id="rightBottom" style={{margin: '5px'}} className="btrigger">right bottom</Button>;
  10. const bottomLeft = <Button id="bottomLeft" style={{margin: '5px'}} className="btrigger">bottom left</Button>;
  11. const bottomRight = <Button id="bottomRight" style={{margin: '5px'}} className="btrigger">bottom right</Button>;
  12. const leftTop = <Button id="leftTop" style={{margin: '5px'}} className="btrigger">left top</Button>;
  13. const leftBottom = <Button id="leftBottom" style={{margin: '5px'}} className="btrigger">left bottom</Button>;
  14. const Content = () => (
  15. <div>
  16. <h4 style={{marginTop: 0}}>balloon title</h4>
  17. <hr/>
  18. <p>
  19. balloon content
  20. </p>
  21. </div>
  22. );
  23. const App = () => (
  24. <div style={{paddingLeft: 320, paddingTop: 100}}>
  25. <div style={{marginLeft: 75}}>
  26. <Balloon trigger={topLeft} align="tl" alignEdge triggerType="click" style={{width: 300}}>
  27. <Content/>
  28. </Balloon>
  29. <Balloon trigger={top} align="t" alignEdge triggerType="click" style={{width: 300}}>
  30. <Content/>
  31. </Balloon>
  32. <Balloon trigger={topRight} align="tr" alignEdge triggerType="click" style={{width: 300}}>
  33. <Content/>
  34. </Balloon>
  35. </div>
  36. <div style={{width: 80, float: 'left'}}>
  37. <Balloon trigger={leftTop} align="lt" alignEdge triggerType="click" style={{width: 300}}>
  38. <Content/>
  39. </Balloon>
  40. <Balloon trigger={left} align="l" alignEdge triggerType="click" style={{width: 300}}>
  41. <Content/>
  42. </Balloon>
  43. <Balloon trigger={leftBottom} align="lb" alignEdge triggerType="click" style={{width: 300}}>
  44. <Content/>
  45. </Balloon>
  46. </div>
  47. <div style={{width: 80, marginLeft: 290}}>
  48. <Balloon trigger={rightTop} align="rt" alignEdge triggerType="click" style={{width: 300}}>
  49. <Content/>
  50. </Balloon>
  51. <Balloon trigger={right} align="r" alignEdge triggerType="click" style={{width: 300}}>
  52. <Content/>
  53. </Balloon>
  54. <Balloon trigger={rightBottom} align="rb" alignEdge triggerType="click" style={{width: 300}}>
  55. <Content/>
  56. </Balloon>
  57. </div>
  58. <div style={{marginLeft: 80, clear: 'both'}}>
  59. <Balloon trigger={bottomLeft} align="bl" alignEdge triggerType="click" style={{width: 300}}>
  60. <Content/>
  61. </Balloon>
  62. <Balloon trigger={bottom} align="b" alignEdge triggerType="click" style={{width: 300}}>
  63. <Content/>
  64. </Balloon>
  65. <Balloon trigger={bottomRight} align="br" alignEdge triggerType="click" style={{width: 300}}>
  66. <Content/>
  67. </Balloon>
  68. </div>
  69. </div>
  70. );
  71. ReactDOM.render(<App />, mountNode);

从浮层内关闭, 事件回调

使用 visible ,属性控制浮层显示, 使 balloon 变为受限组件。

Balloon 气泡提示 - 图4

查看源码在线预览

  1. import { Button, Balloon } from '@alifd/next';
  2. class App extends React.Component {
  3. constructor(props) {
  4. super(props);
  5. this.state = {
  6. visible: false
  7. };
  8. }
  9. hide() {
  10. this.setState({
  11. visible: false
  12. });
  13. }
  14. // onVisibleChange callback will be triggered when visible changes.
  15. // For example, for click type, it'll be triggered when clicking the button and later the other areas;
  16. // for hover type, it'll be triggered when mouse enter and mouse leave
  17. handleVisibleChange(visible) {
  18. this.setState({visible});
  19. }
  20. onClose() {
  21. console.log('onClose doing!');
  22. }
  23. afterClose() {
  24. console.log('afterClose doing!');
  25. }
  26. render() {
  27. const visibleTrigger = <Button type="primary" style={{margin: '5px'}}>click to popup the card</Button>;
  28. const clickTrigger = <Button type="primary" style={{margin: '5px'}}>hover to popup the card</Button>;
  29. const content = (<div>
  30. click the button<br/>
  31. <a style={{right: 0}} id="confirmBtn" onClick={this.hide.bind(this)}>confirm</a>
  32. <a style={{marginLeft: '4px'}} id="cancelBtn" onClick={this.hide.bind(this)}>cancel</a>
  33. </div>);
  34. return (
  35. <div>
  36. <Balloon trigger={visibleTrigger}
  37. triggerType="click"
  38. visible={this.state.visible}
  39. onVisibleChange={this.handleVisibleChange.bind(this)}
  40. >
  41. {content}
  42. </Balloon>
  43. <Balloon trigger={clickTrigger}
  44. triggerType="hover"
  45. onClose={this.onClose.bind(this)}
  46. afterClose={this.afterClose.bind(this)}>
  47. {content}
  48. </Balloon>
  49. </div>
  50. );
  51. }
  52. }
  53. ReactDOM.render(<App />, mountNode);

close按钮事件,手动控制visible

使用 visible,属性控制浮层显示, 使balloon变为受限组件。

Balloon 气泡提示 - 图5

查看源码在线预览

  1. import { Button, Balloon } from '@alifd/next';
  2. class App extends React.Component {
  3. constructor(props) {
  4. super(props);
  5. this.state = {
  6. visible: false
  7. };
  8. }
  9. // triggered every time visible becomes false
  10. onClose() {
  11. console.log('onClose doing!');
  12. }
  13. onClick() {
  14. this.setState({visible: true});
  15. }
  16. render() {
  17. const visibleTrigger = <Button onClick={this.onClick.bind(this)} type="primary">click to pupup the card</Button>;
  18. const content = (<div>content</div>);
  19. return (
  20. <div style={{marginBottom: '100px'}}>
  21. <Balloon trigger={visibleTrigger}
  22. triggerType="click"
  23. visible={this.state.visible}
  24. onClose={this.onClose.bind(this)} >
  25. {content}
  26. </Balloon>
  27. </div>
  28. );
  29. }
  30. }
  31. ReactDOM.render(<App />, mountNode);

嵌套浮层问题

浮层中如果又有浮层,比如在Balloon中有DatePicker/Select的浮层, DatePicker选择时,Balloon浮层也会关闭。可以用 followTrigger解决。

Balloon 气泡提示 - 图6

查看源码在线预览

  1. import { Button, Balloon, DatePicker, Select } from '@alifd/next';
  2. import moment from 'moment';
  3. const showSelect = <Button className="btrigger">Show Select</Button>;
  4. const showDatePicker = <Button className="btrigger">Show DatePicker</Button>;
  5. const innerButton = <Button className="btrigger">Show Inner Balloon</Button>;
  6. const dateValue = moment('2018-01-01', 'YYYY-MM-DD', true);
  7. const App = () => (
  8. <div className="container nested">
  9. <Balloon type="primary" autoFocus trigger={showSelect} closable={false} triggerType="click">
  10. <Select dataSource={['apple', 'banana', 'orange']} followTrigger />
  11. </Balloon>
  12. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  13. <Balloon type="primary" autoFocus trigger={showDatePicker} closable={false} triggerType="click">
  14. <DatePicker defaultValue={dateValue} followTrigger />
  15. </Balloon>
  16. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  17. <Balloon type="primary" autoFocus trigger={innerButton} closable={false} triggerType="click">
  18. <Balloon trigger={<Button type="primary">please click</Button>} followTrigger triggerType="click">
  19. nesting balloon content
  20. </Balloon>
  21. </Balloon>
  22. </div>
  23. );
  24. ReactDOM.render(<App />, mountNode);
  1. .container.nested {
  2. margin-bottom: 50px;
  3. }

tooltip

简化的Balloon, 只能设置align, trigger和children, 触发条件是hover.

Balloon 气泡提示 - 图7

查看源码在线预览

  1. import { Button, Balloon } from '@alifd/next';
  2. const Tooltip = Balloon.Tooltip;
  3. const top = <Button style={{margin: '5px'}} id="top" className="btrigger">top</Button>;
  4. const right = <Button style={{margin: '5px'}}id="right" className="btrigger">right</Button>;
  5. const bottom = <Button style={{margin: '5px'}} id="bottom" className="btrigger">bottom</Button>;
  6. const left = <Button style={{margin: '5px'}} id="left" className="btrigger">left</Button>;
  7. const topLeft = <Button style={{margin: '5px'}} id="topLeft" className="btrigger">top left</Button>;
  8. const topRight = <Button style={{margin: '5px'}} id="topRight" className="btrigger">top right</Button>;
  9. const rightTop = <Button style={{margin: '5px'}} id="rightTop" className="btrigger">right top</Button>;
  10. const rightBottom = <Button style={{margin: '5px'}} id="rightBottom" className="btrigger">right bottom</Button>;
  11. const bottomLeft = <Button style={{margin: '5px'}} id="bottomLeft" className="btrigger">bottom left</Button>;
  12. const bottomRight = <Button style={{margin: '5px'}} id="bottomRight" className="btrigger">bottom right</Button>;
  13. const leftTop = <Button style={{margin: '5px'}} id="leftTop" className="btrigger">left top</Button>;
  14. const leftBottom = <Button style={{margin: '5px'}} id="leftBottom" className="btrigger">left bottom</Button>;
  15. const App = () => (
  16. <div style={{paddingLeft: 220, paddingTop: 100}}>
  17. <div style={{marginLeft: 75}}>
  18. <Tooltip trigger={topLeft} align="tl">text text</Tooltip>
  19. <Tooltip trigger={top} align="t">text text</Tooltip>
  20. <Tooltip trigger={topRight} align="tr">text text</Tooltip>
  21. </div>
  22. <div style={{width: 80, float: 'left'}}>
  23. <Tooltip trigger={leftTop} align="lt">text text</Tooltip>
  24. <Tooltip trigger={left} align="l">text text</Tooltip>
  25. <Tooltip trigger={leftBottom} align="lb">text text</Tooltip>
  26. </div>
  27. <div style={{width: 80, marginLeft: 290}}>
  28. <Tooltip trigger={rightTop} align="rt">text text</Tooltip>
  29. <Tooltip trigger={right} align="r">text text</Tooltip>
  30. <Tooltip trigger={rightBottom} align="rb">text text</Tooltip>
  31. </div>
  32. <div style={{marginLeft: 80, clear: 'both'}}>
  33. <Tooltip trigger={bottomLeft} align="bl">text text</Tooltip>
  34. <Tooltip trigger={bottom} align="b">text text</Tooltip>
  35. <Tooltip trigger={bottomRight} align="br">text text</Tooltip>
  36. </div>
  37. </div>
  38. );
  39. ReactDOM.render(<App />, mountNode);
  1. .code-box-demo .sui-btn {
  2. margin-right: 1em;
  3. margin-bottom: 1em;
  4. }

无障碍

弹层id, 传入值才会支持无障碍。

Balloon 气泡提示 - 图8

查看源码在线预览

  1. import { Button, Balloon, Input } from '@alifd/next';
  2. import moment from 'moment';
  3. const { Tooltip } = Balloon;
  4. const innerButton = <Button className="btrigger">Fill in form</Button>;
  5. const triggerTooltip = <Button style={{margin: '5px'}}>show tooltip</Button>;
  6. const App = () => (
  7. <div className="container nested">
  8. <Balloon id="inner-a11y-balloon-1" autoFocus trigger={<Button type="primary">Fill in sub-form</Button>} popupContainer={(trigger) => trigger.parentNode} triggerType="click">
  9. please input your age:
  10. <Input placeholder="Age" size="small" label="Age :" id="balloon-input-1" /><br /><br />
  11. </Balloon>
  12. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  13. <Balloon id="a11y-balloon" type="primary" autoFocus trigger={innerButton} triggerType="click">
  14. <Balloon id="inner-a11y-balloon" autoFocus trigger={<Button type="primary">Fill in sub-form</Button>} popupContainer={(trigger) => trigger.parentNode} triggerType="click">
  15. please input your age:
  16. <Input placeholder="Age" size="small" label="Age :" id="balloon-input-2" /><br /><br />
  17. </Balloon>
  18. <br />
  19. please input your name:
  20. <Input placeholder="Name" size="small" label="Name :" id="balloon-input-3" /><br /><br />
  21. </Balloon>
  22. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  23. <Tooltip trigger={triggerTooltip} id="aria-tooltip">
  24. <p>This is content for tooltip.</p>
  25. </Tooltip>
  26. </div>
  27. );
  28. ReactDOM.render(<App />, mountNode);
  1. .container.nested {
  2. margin-left: 100px;
  3. margin-bottom: 50px;
  4. }

相关区块

Balloon 气泡提示 - 图9

暂无相关区块