# 通用扩展组件

## 案例演示

### helptip 基本使用

---demo
```js
import { HelpTip } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '20em', display: 'inline-block', padding: '1em' }}>
    <HelpTip onClick={() => {console.log('click help tip!');}} />
  </div>
), _react_runner_);
```
---demoend

#### HelpTip 帮助提示 props

> 界面中需要强调某一模块，或者进行引导提示时使用

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | String | `amos-help-tip` | 样式前缀 |
| onClick | func | - | 点击事件 |

### Paragraph 基本使用

---demo
```js
import { Paragraph } from 'amos-framework';

const htmlContent = `
  <div style="color: red;">
    我是html 内容
  </div>
`;

ReactDOM.render((
  <div style={{ width: '20em', display: 'inline-block', padding: '1em' }}>
    <Paragraph html={htmlContent} />
  </div>
), _react_runner_);
```
---demoend

#### Paragraph 段落 props

> 需要插入 `html` 时使用

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | String | `amos-paragraph` | css class 前缀 |
| className | String | - | 自定义 className |
| html | string | - | html 文本 |

### EmptyData 基本使用

---demo
```js
import { EmptyData } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '20em', display: 'inline-block', padding: '1em' }}>
    <h5>默认</h5>
    <EmptyData style={{ width: '200px' }} />
    <h5>定制</h5>
    <EmptyData style={{ width: '200px' }}>
      <div style={{ lineHeight: 2 }}>
        <div>你还没有创建目标哦</div>
        <div>马上去<a>添加目标</a></div>
      </div>
    </EmptyData>
    <h2>页面级</h2>
    <EmptyData style={{ width: '200px' }} type="large">
      <div>你还没有创建目标哦</div>
      <Button>添加目标</Button>
    </EmptyData>
  </div>
), _react_runner_);
```
---demoend

#### EmptyData 空数据 props

> 需要显示空数据作为默认显示

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | String | `amos-empty-data` | css class 前缀 |
| className | String | - | 自定义 className |
| style | object | - | 样式 |
| children | `String or ReactNode` | `暂无数据` | 内容 |
| type | String | `type` | 类型，除了默认值，可选值为 `normal、large` |
| icon | String | `defaultIcon` | icon 背景 |
| largeIcon | String | `defaultIcon` | 较大 icon 背景 |

### User 基本使用

---demo
```js
import { User } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '20em', display: 'inline-block', padding: '1em' }}>
    <User
      userPic="https://tinypng.com/images/panda-chewing.png"
      basicInfo={<div>admin <p>admin@admin.com</p></div>}
      isCustomProfile
      extra={
        <ul>
          <li>基本资料</li>
          <li>个人设置</li>
          <li>其他信息</li>
        </ul>
      }
    />
    <User
      userPic="https://tinypng.com/images/panda-happy.png"
      basicInfo={{ userName: 'admin', subInfo: 'admin@admin.com' }}
      extra={
        <ul>
          <li>基本资料</li>
          <li>个人设置</li>
          <li>其他信息</li>
        </ul>
      }
    />
  </div>
), _react_runner_);
```
---demoend

#### User 用户 props

> 系统用户

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| userPic | string | `amos-empty-data` | 用户图片 |
| basicInfo | ReactNode | - | 用户基本信息 |
| extra | ReactNode | - | 用户额外信息，可用于设置更多的操作 |
| handleLogOut | func | - | 注销事件 |
| logoutTip | string | `注销` | 注销按钮文本内容 |

### Bullet 基本使用

---demo
```js
import { Bullet } from 'amos-framework';

ReactDOM.render((
  <div style={{ display: 'inline-block', padding: '1em' }}>
     <div>
        <h4>基本使用</h4>
        <Bullet title="折扣">限购一份</Bullet>
        <Bullet title="npm">v6.0.1</Bullet>
        <Bullet title="build" color="red" >failure</Bullet>
        <Bullet title="download" color="green" >10k</Bullet>
        <Bullet title="coverage">35%</Bullet>
        <Bullet title="build">unknown</Bullet>
        <Bullet disabled title="disabled">disabled</Bullet>
      </div>
      <div>
        <h4>盾牌</h4>
        <Bullet type="shield" title="折扣">限购一份</Bullet>
        <Bullet type="shield" title="npm">v6.0.1</Bullet>
        <Bullet type="shield" title="build" color="red" >failure</Bullet>
        <Bullet type="shield" title="download" color="green" >10k</Bullet>
        <Bullet type="shield" title="coverage">35%</Bullet>
        <Bullet type="shield" title="build">unknown</Bullet>
        <Bullet type="shield" disabled title="disabled">disabled</Bullet>
      </div>
      <div>
        <h4>标签的方式</h4>
        <Bullet type="shield">限购一份</Bullet>
        <Bullet type="shield">v6.0.1</Bullet>
        <Bullet type="shield">failure</Bullet>
        <Bullet type="shield">10k</Bullet>
        <Bullet type="shield">35%</Bullet>
        <Bullet type="shield">unknown</Bullet>
        <Bullet type="shield">disabled</Bullet>
      </div>
  </div>
), _react_runner_);
```
---demoend

#### Bullet 弹头 props

> 简单显示标签信息时使用，如版本、售价、促销等场景

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | String | `amos-bullet` | css class 前缀 |
| className | String | - | 自定义 className |
| children | `String or ReactNode` | - | 弹头内容 |
| title | `String or ReactNode` | - | 弹头标题 |
| type | String | - | 类型，除了默认值外，可选值 `shield` 盾牌样式 |
| color | String | `#345fa6` | 弹头颜色 |
| disabled | Boolean | `false` | 禁用 |

### Shuttle 基本使用

---demo
```js
import { Shuttle } from 'amos-framework';

const datas = [
  { key: 'one', descr: '页面1' },
  { key: 'two', descr: '页面2' },
  { key: 'three', descr: '页面3' },
  { key: 'four', descr: '页面4' },
  { key: 'five', descr: '页面5' }
];

class Demo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      open: false
    };
  }

  genMapper = () => {
    return datas.map(d => {
      return {
        key: d.key,
        content: this.renderContent(d)
      };
    });
  }

  renderContent(item){
    return (
      <div style={{ background: '#ff00ff' }}>{item.descr}</div>
    );
  }

  render() {
    const { open } = this.state;
    return (
      <Shuttle
        dataSource={this.genMapper()}
        style={{ height: '15em', background: 'rgba(208, 208, 208, 0.5)' }}
        contentStyle={{ height: '10em', background: '#ccc' }}
      />
    );
  }
}

ReactDOM.render(<Demo />, _react_runner_);
```
---demoend

### Verifycode 基本使用

---demo
```js
import { Verifycode } from 'amos-framework';

class Demo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: '',
      codeBlob: ''
    };
  }

  componentDidMount() {
    // this.onRefreshCode();
  }

  onRefreshCode = () => {
    // 异步获取验证码，
    fetch('http://172.16.10.67:8800/system/valicode/aabb').then(res => res.blob()).then(data => {
      const _URL = window.URL || window.webkitURL;
      const objectURL = _URL.createObjectURL(data);
      this.setState({ codeBlob: objectURL });
    })
  }

  onChange = (e) => {
    const value = e.target.value;
    this.setState({
      value
    });
    console.log('Verifycode', value);
  }

  render() {
    const { value, codeBlob } = this.state;
    return (
      <Verifycode
        addonIcon="info"
        placeholder="请输入验证码"
        value={value}
        codeBlob={codeBlob}
        onCodeClick={this.onRefreshCode}
        onChange={this.onChange}
      />
    );
  }
}

ReactDOM.render(<Demo />, _react_runner_);
```
---demoend

### DownloadBrowsers 基本使用

浏览器下载地址，可以设置为本地也可以设置为官网。该界面和判断浏览器类型与版本方法配合使用更佳。

---demo
```js
import { DownloadBrowsers } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    <DownloadBrowsers />
  </div>
), _react_runner_);
```
---demoend

#### DownloadBrowsers props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| options | Object | - | 自定义配置项 |

默认配置为：

```js
const options = {
  header: '对不起，您的浏览器版本过低,请选择如下浏览器以支持本系统:',
  urls: [
    { id: 'fifox', href: 'https://www.firefox.com.cn/download/', describe: '下载火狐浏览器' },
    { id: 'chrome', href: 'https://www.google.cn/chrome/', describe: '下载谷歌浏览器' }
  ]
}
```


### UnitNumber 基本使用

---demo
```js
import { UnitNumber } from 'amos-framework';

function handleChange(value){
  console.log(value);
}
function handleUnitChange(value){
  console.log(value);
}

function parseValue(val){
  const num = parseFloat(val);
  const unit = String(val).replace(num, '') || 'px';
  return [num, unit];
}

class CDemo extends Component {
  state = {
    value: 0
  };

  onChange = (value) => {
    const [num, unit] = parseValue(this.state.value);
    this.setState({
      value: `${value}${unit}`
    });
  }

  handleUnitChange = (value) => {
    const [num, unit] = parseValue(this.state.value);
    this.setState({
      value: `${num}${value}`
    });
  }

  render(){
    const { value } = this.state;
    const [num, unit] = parseValue(value);
    console.log(value);
    return <UnitNumber value={num} unitValue={unit} onChange={this.onChange} handleUnitChange={this.handleUnitChange} />;
  }
}

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    像素输入：<UnitNumber onChange={handleChange} handleUnitChange={handleUnitChange} />
    <br />
    禁用单位：<UnitNumber disableUnitSelect onChange={handleChange} />
    <br />
    案例：<CDemo />
  </div>
), _react_runner_);
```
---demoend

### PropertyNumber 基本使用

---demo
```js
import { PropertyNumber } from 'amos-framework';

function handleChange(value){
  console.log(value);
}

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    像素输入：<PropertyNumber onChange={handleChange} addonAfter="X" />
    <br />
    启用100%：<PropertyNumber enablePercent onChange={handleChange} addonAfter="W" />
  </div>
), _react_runner_);
```
---demoend

### BoxShadow 基本使用

`box-shadow` 标准格式 `[inset] x y blur spread color`。如果不满足格式，将会重置为传入的 value 值。如果有复杂的校验，可以禁用 input 输入

---demo
```js
import { BoxShadow } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    基本使用: <BoxShadow defaultValue="1px 1px #eee" />
    <br />
    禁用输入：<BoxShadow defaultValue="1px 1px #eee" disabledInput />
  </div>
), _react_runner_);
```
---demoend

### TextShadow 基本使用

`text-shadow` 标准格式 `x y blur color`。如果不满足格式，将会重置为传入的 value 值。如果有复杂的校验，可以禁用 input 输入

---demo
```js
import { TextShadow } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    基本使用: <TextShadow defaultValue="1px 1px #eee" />
    <br />
    禁用输入：<TextShadow defaultValue="1px 1px #eee" disabledInput />
  </div>
), _react_runner_);
```
---demoend

### Border 基本使用

`border` 标准格式 `[borderWith] [borderStyle] [borderColor]`。如果不满足格式，将会重置为传入的 value 值。如果有复杂的校验，可以禁用 input 输入

---demo
```js
import { Border } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    基本使用: <Border defaultValue="1px solid #eee" />
    <br />
    禁用输入：<Border defaultValue="1px solid #eee" disabledInput />
  </div>
), _react_runner_);
```
---demoend

### BorderRadius 基本使用

`border-radius-shadow` 标准格式 `lt [rt] [lb] [rb]`。如果不满足格式，将会重置为传入的 value 值。如果有复杂的校验，可以禁用 input 输入

---demo
```js
import { BorderRadius } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    基本使用: <BorderRadius defaultValue="1px 1px" />
    <br />
    禁用输入：<BorderRadius defaultValue="1px 1px" disabledInput />
  </div>
), _react_runner_);
```
---demoend

### AnglePicker 基本使用

---demo
```js
import { AnglePicker } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    基本使用: <AnglePicker defaultValue={0} />
    <br />
    slider类型：<AnglePicker defaultValue={0} type="slider" />
    input类型：<AnglePicker defaultValue={0} type="input" />
  </div>
), _react_runner_);
```
---demoend

### PaddingMargin 基本使用

---demo
```js
import { PaddingMargin } from 'amos-framework';

ReactDOM.render((
  <div style={{ width: '100%', display: 'inline-block', padding: '1em' }}>
    内边距: <PaddingMargin defaultValue="10px" />
    外边距: <PaddingMargin defaultValue="10px" />
  </div>
), _react_runner_);
```
---demoend

### Feedback 使用案例

#### Feedback 基本使用

系统放置反馈按钮区，默认在右下角

---demo
```js
import { Feedback, Button } from 'amos-framework';

function openLink(){
  window.open('https://support.qq.com/products/317400', '_blank');
}

const content = (
  <ul>
    <li>问题1</li>
    <li>问题2</li>
    <li>问题3</li>
  </ul>
);

ReactDOM.render((
  <Feedback>
    <Button title="反馈一下" icon="message" circle useInnerIcon onClick={openLink}/>
    <Button title="喜欢作者" icon="collection" circle useInnerIcon/>
    <Popover
      content={content}
      direction="left"
      align="bottom"
    >
      <Button title="问题" icon="info" circle useInnerIcon/>
    </Popover>
  </Feedback>
), _react_runner_);
```
---demoend

#### Feedback 高级使用

右下角回馈高级使用

---demo
```js
import { Feedback, Button } from 'amos-framework';

function openLink(){
  window.open('https://support.qq.com/products/317400', '_blank');
}

const effectProps = {
  normal: {
    right: 6,
    bottom: -15,
    opacity: 0.6
  },
  active: {
    right: 6,
    bottom: 5,
    opacity: 1
  }
};

ReactDOM.render((
  <Feedback mode="effect" effectProps={effectProps}>
    <Button title="反馈一下" icon="message" circle useInnerIcon onClick={openLink}/>
  </Feedback>
), _react_runner_);
```
---demoend

#### Feedback 高级使用之子节点为function

方法的参数 `status` 有两个取值，分别为 `normal` 和 `active`，当值为 normal 时，表示是常态。

---demo
```js
import { Feedback, Button } from 'amos-framework';

function openLink(){
  window.open('https://support.qq.com/products/317400', '_blank');
}

const effectProps = {
  normal: {
    right: 100,
    bottom: 0,
    opacity: 0.6
  },
  active: {
    right: 100,
    bottom: 0,
    opacity: 1
  }
};

ReactDOM.render((
  <Feedback mode="effect" effectProps={effectProps}>
    {
      status => {
        if (status === 'normal'){
          return <div style={{ height: 5, background: 'red', width: 30 }} />
        }
        return <Button title="反馈一下" icon="message" circle useInnerIcon onClick={openLink}/>;
      }
    }
  </Feedback>
), _react_runner_);
```
---demoend

#### Feedback 反馈 props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | String | `amos-feedback` | 样式前缀 |
| className | String | - | 自定义样式名 |
| style | object | - | 自定义内联样式 |
| mode | String | base | 模式，默认支持 `'base', 'effect', 'custom'` 类型，也可以自定义其它类型 |
| children | ReactNode or `status => ReactNode` | - | 内容节点，如果是一个 func 时，方法的参数 `status` 有两个取值，分别为 `normal` 和 `active`，当值为 normal 时，表示是常态 |

### Status 状态基本使用

---demo
```js
import { Status } from 'amos-framework';

function openLink(){
  window.open('https://www.baidu.com', '_blank');
}

ReactDOM.render((
  <div className="inline-demo">
    <Status title="正常" icon="message" onClick={openLink} />
    <br />
    <Status title="故障" type="success" />
    <br />
    <Status title="故障" type="processing" />
    <br />
    <Status title="故障" type="default" />
    <br />
    <Status title="故障" type="error" />
    <br />
    <Status title="故障" type="warning" />
    <br />
    <Status title="图片路径" icon="warning" type="warning" />
  </div>
), _react_runner_);
```
---demoend

#### Status 状态 props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | String | `amos-status` | 样式前缀 |
| className | String | - | 自定义样式名 |
| style | object | - | 自定义内联样式 |
| icon | `string or ReactNode` | - | icon 内容，如果是 string 类型，仅支持内置 icon 库 |
| title | string | - | 标题内容 |
| onClick | func | - | 点击事件 |
| type | String | - | 类型，默认支持 `'success', 'processing', 'default', 'error', 'warning'` 类型，可自定义类型 |

### CopyInput 输入复制

---demo
```js
import { CopyInput } from 'amos-framework';

ReactDOM.render((
  <div className="inline-demo">
    <CopyInput value="很长的内容" />
  </div>
), _react_runner_);
```
---demoend

#### CopyInput props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| className | String | - | 自定义样式名 |
| readOnly | object | - | 自定义内联样式 |
| value | string | - | 输入框内容 |
| buttonProps | object | - | 按钮 props |
| inputProps | object | - | 输入框 props |

### PositionFixed fixed 布局

---demo
```js
import { PositionFixed } from 'amos-framework';

ReactDOM.render((
  <div>
    <PositionFixed bottom="16px"><span style={{ color: 'red' }}>固定在body的底部</span></PositionFixed>
    <div style={{ position: 'relative', transform: 'scale(1)', height: 300, background: '#eee' }}>
      <PositionFixed bottom="16px"><span style={{ color: '#790092' }}>父节点设置了transform，则固定在相对父节点的底部</span></PositionFixed>
    </div>
  </div>
), _react_runner_);
```
---demoend

参考： [position#fixed](https://developer.mozilla.org/zh-CN/docs/Web/CSS/position#fixed)

#### PositionFixed props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| className | String | - | 自定义样式名 |
| left | `String or Number`| - | 左边位置 |
| top | `String or Number` | - | 顶部位置 |
| right | `String or Number` | - | 右边位置 |
| bottom | `String or Number` | - | 底部位置 |

### Skeleton 骨架屏

---demo
```js
import { Skeleton } from 'amos-framework';

const stripe = [
  { key: '1', items: ['12', '12'] },
  { key: '2', items: ['10', '12'] },
  { key: '3', items: ['8', '4', '10'] }
];

ReactDOM.render((
  <div>
    <Skeleton />
    <br />
    <Skeleton stripe={stripe} />
  </div>
), _react_runner_);
```
---demoend

#### Skeleton props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | String | `amos-skeleton` | 自定义样前缀 |
| className | String | - | 自定义样式名 |
| padding | `String or Number`| - | 内边距 |
| stripe | Array | - | 骨架数据 |

stripe 数据格式，由 key 和 items 组成的对象数组，items 的每一项符合 `Col`，即各项和为 `24`

```js
const stripe = [
  { key: '1', items: ['24'] },
  { key: '2', items: ['10', '12'] },
  { key: '3', items: ['8', '4', '11'] }
];
```


### Flex 布局

---demo
```js
import { Flex } from 'amos-framework';

const baseStyle = {
  width: '25%',
  height: 30,
};

ReactDOM.render((
  <Flex gap="mid" vertical>
    <Flex>
      {Array.from({ length: 4 }).map((_, i) => (
        <div key={i} style={{ ...baseStyle, backgroundColor: i % 2 ? '#1677ff' : '#1677ffbf' }} />
      ))}
    </Flex>
    <br />
    <Flex vertical>
      {Array.from({ length: 4 }).map((_, i) => (
        <div key={i} style={{ ...baseStyle, backgroundColor: i % 2 ? '#1677ff' : '#1677ffbf' }} />
      ))}
    </Flex>
  </Flex>
), _react_runner_);
```
---demoend

#### Flex props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| vertical | boolean | `false` | flex 主轴的方向是否垂直，使用 `flex-direction: column` |
| center | boolean | `false` | 该值设置为true，则直接设置 `justify-content: cetner; align-items: center`, 优先级高于 justify 和 align 的设置|
| wrap | `string` 参考 [flex-wrap](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-wrap) | nowrap | 设置元素单行显示还是多行显示 |
| justify | `string` 参考 [justify-content](https://developer.mozilla.org/zh-CN/docs/Web/CSS/justify-content) | normal | 设置元素在主轴方向上的对齐方式 |
| align | `string` 参考 [align-items](https://developer.mozilla.org/zh-CN/docs/Web/CSS/align-items) | normal | 设置元素在交叉轴方向上的对齐方式 |
| flex | `string or number` 参考 [flex](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex) | normal | flex CSS 简写属性 |
| gap | `sm、mid、lg、or string、number` | - | 设置网格之间的间隙 |
| component | `React.ComponentType` | `div` | 自定义元素类型 |
| inline | Boolean | - | 是否是行内元素 flex 布局， 设置为 true，则 display值为: `inline-flex` |

### FlexWrap 布局

flex 布局，整体全部居中，多行最后一行居左。只有一行时，居中。

该案例，可以通过缩放浏览器查看效果。

---demo
```js
import { FlexWrap } from 'amos-framework';

const itemStyle = {
  width: 300,
  height: 150,
  background: '#eee'
};

const Item = () => <div style={itemStyle}>item</div>

ReactDOM.render((
  <div>
    <FlexWrap>
      <Item />
      <Item />
      <Item />
    </FlexWrap>
    <FlexWrap className="mt-20">
      <Item />
      <Item />
      <Item />
      <Item />
      <Item />
      <Item />
    </FlexWrap>
  </div>
), _react_runner_);
```
---demoend

#### Flex props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| className | string | - | 自定义样式名 |
| children | ReactNode | - | 内容节点 |
| gap | Number | 16 | item 间距 |


### ResizeLine 缩放线

---demo
```js
import { ResizeLine, Flex } from 'amos-framework';

const _stretchConfig = {
  offsetX: 42,
  offsetY: 42,
  min: 200,
  max: 500
};

const _stretch = {
  position: 'fixed',
  width: '200px',
  background: 'white',
  height: 'calc(100% - 78px)'
};

const style = {
  position: 'absolute',
  top: '41px',
  bottom: 0,
  left: 0,
  zIndex: 3,
  width: '242px'
};

const left = {
  position: 'relative',
  overflow: 'hidden',
  width: '42px',
  height: '100%',
  background: '#345fa6'
};

const right = {
  position: 'absolute',
  top: 0,
  right: 0,
  width: 'calc(100% - 41px)',
  height: '100%',
  border: '1px solid #eee',
  // 确保 fixed 可以相对于该节点
  transform: 'scale(1)'
};

const full = {
  width: '100%',
  height: '100%'
};

const leftCard = {
  background: '#eee'
};

class Demo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pageSize: 200,
      offsetX: 0,
      offsetY: 0
    };
    this.rootRef = React.createRef();
  }

  componentDidMount() {
    this._calcOffset();
  }

  _calcOffset = () => {
    if (this.rootRef.current){
      const offset = this.rootRef.current.getBoundingClientRect();
      this.setState({
        offsetX: offset.left,
        offsetY: offset.top
      });
    }
  }

  handleResizeChange = (pageSize) => {
    this.setState({
      pageSize
    });
  }

  render() {
    const { pageSize, offsetX, offsetY } = this.state;
    const stretchStyle = { ..._stretch, width: pageSize };

    const stretchConfig = {
      ..._stretchConfig,
      offsetX,
      offsetY
    };

    return (
      <div style={style} ref={this.rootRef}>
        <div style={full}>
          <div style={left} />
            <div style={right}>
              <div style={stretchStyle}>
                <div ref={this.rootRef} style={full}>
                  <Flex style={{ ...leftCard, ...full }} center>宽度为：{pageSize}</Flex>
                </div>
                <ResizeLine onResizeChange={this.handleResizeChange} {...stretchConfig} />
              </div>
            </div>
          </div>
      </div>
    );
  }
}

ReactDOM.render((
  <div style={{ width: '100%', height: 300 }}>
    <Demo />
  </div>
), _react_runner_);
```
---demoend

#### ResizeLine props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | string | `amos-resizeline` | css class 前缀 |
| className | string | - | css class |
| onResizeChange | func | - | resize 左侧宽度变动时的回调 |
| offsetX | Number | - | resizer 目标左侧内容区域的 offsetLeft 值 |
| offsetY | Number | - | resizer 目标左侧内容区域的 offsetTop 值 |
| min | Number | - | 最小缩放值 |
| max | Number | - | 最大缩放值 |


### FloatRoller 滚动广告

---demo
```js
import { FloatRoller } from 'amos-framework';

const rootStyle = {
  width: 540,
  height: 260,
  fontWeight: 'bold',
  background: 'yellow'
};

const content = (
  <div style={{ fontSize: 30 }}>
    <div style={{ textAlign: 'center', color: 'red' }}>！！！重要提醒</div>
    <div style={{ color: 'blue' }}>根据国家信息化及省局密评要求，特种设备智慧监管平台将采用双认证进行登录身份鉴别</div>
    <div style={{ color: 'red' }}>登录方式：用户名+口令+短信验证码</div>
  </div>
);

ReactDOM.render(<FloatRoller style={rootStyle} content={content} />, _react_runner_);
```
---demoend

#### FloatRoller props

| params | type | default | description |
|--------- |-------- |--------- |-------- |
| prefixCls | string | `amos-float-roller` | 样式前缀 |
| className | string | - | 自定义样式 |
| style | object | - | 自定义内联样式 |
| content | ReactNode | - | 内容组件 |
| contentStyle | object | - | 内容区自定义内联样式 |
| speed | number | 20 | 滚动速度 |
| quiet | boolean | - | 是否静止的 |
| disabled | boolean | - | 禁用，直接不显示 |


### LightSpot 案例

> 鼠标悬浮时，显示跟随效果

---demo
```js
import { LightSpot } from 'amos-framework';

const cStyle = {
  background: '#345fa6',
  padding: 16
};

ReactDOM.render((
  <LightSpot style={cStyle}>
    鼠标浮在这段文字上面试试
  </LightSpot>
), _react_runner_);
```
---demoend
