feat(zhst/biz): 新增无限滚动列表组件
This commit is contained in:
parent
57af643093
commit
aea6e2ec4c
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@ -2,9 +2,9 @@
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"name": "http://localhost:8000/metas/big-image-preview",
|
||||
"name": "lambo",
|
||||
"request": "launch",
|
||||
"url": "http://localhost:8000/metas/big-image-preview"
|
||||
"url": "http://localhost:8000/metas"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,5 +1,18 @@
|
||||
# @zhst/biz
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 视频添加 OD 框,查看大图首次点击修复
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @zhst/meta@0.15.0
|
||||
- @zhst/func@0.10.2
|
||||
- @zhst/hooks@0.9.2
|
||||
|
||||
## 0.16.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@zhst/biz",
|
||||
"version": "0.16.1",
|
||||
"version": "0.17.0",
|
||||
"description": "业务库",
|
||||
"keywords": [
|
||||
"business",
|
||||
@ -47,6 +47,7 @@
|
||||
"antd": "^5.12.5",
|
||||
"classnames": "^2.5.1",
|
||||
"dayjs": "^1.11.10",
|
||||
"rc-util": "^5.38.1"
|
||||
"rc-util": "^5.38.1",
|
||||
"react-infinite-scroll-component": "^6.1.0"
|
||||
}
|
||||
}
|
||||
|
@ -17,4 +17,5 @@ export { default as ViewLargerImageModal, useViewLargerImageModal } from './View
|
||||
export type { VideoPlayerCardProps } from './VideoPlayerCard'
|
||||
export { default as VideoPlayerCard } from './VideoPlayerCard'
|
||||
export { default as RealTimeMonitor } from './RealTimeMonitor'
|
||||
|
||||
export { default as InfiniteList } from './infiniteList'
|
||||
// export type { InfiniteListProps, InfiniteListRefProps } from './infiniteList'
|
||||
|
126
packages/biz/src/infiniteList/InfiniteList.tsx
Normal file
126
packages/biz/src/infiniteList/InfiniteList.tsx
Normal file
@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Created by jiangzhixiong
|
||||
*/
|
||||
|
||||
import React, { forwardRef, ReactNode, useContext, useImperativeHandle, useRef } from 'react'
|
||||
import { ConfigProvider } from '@zhst/meta';
|
||||
import { Divider, Flex } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import InfiniteScroll from 'react-infinite-scroll-component';
|
||||
import { SearchCard, SearchCardProps } from './components';
|
||||
import './index.less'
|
||||
|
||||
const { ConfigContext } = ConfigProvider
|
||||
|
||||
export interface InfiniteListProps {
|
||||
type?: 'custom' | 'auto'
|
||||
prefixCls?: string;
|
||||
height?: number;
|
||||
itemRender?: (data?: any) => React.ReactNode
|
||||
loading?: boolean; //
|
||||
data: any[];
|
||||
targetId?: string; // 滚动列表 ID
|
||||
loadMore?: (data?: any) => any;
|
||||
params?: {
|
||||
[key: string]: any;
|
||||
}
|
||||
hasMore: boolean;
|
||||
endMessage?: ReactNode
|
||||
loadingMessage?: ReactNode
|
||||
onItemClick?: (data: any) => void;
|
||||
searchCardProps?: SearchCardProps
|
||||
}
|
||||
|
||||
export interface InfiniteListRefProps {
|
||||
|
||||
}
|
||||
|
||||
const InfiniteList = forwardRef<InfiniteListRefProps, InfiniteListProps>((props, ref) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
height,
|
||||
type = 'auto',
|
||||
loadingMessage = <p style={{ textAlign: 'center' }}>加载中...</p>,
|
||||
targetId = 'scrollableDiv',
|
||||
itemRender,
|
||||
hasMore,
|
||||
onItemClick,
|
||||
loadMore,
|
||||
data = [],
|
||||
endMessage = <Divider plain>没有更多数据了...🤐</Divider>,
|
||||
searchCardProps
|
||||
} = props
|
||||
const { getPrefixCls } = useContext(ConfigContext);
|
||||
const componentName = getPrefixCls('biz-infinite-list', customizePrefixCls);
|
||||
const listRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
|
||||
}))
|
||||
|
||||
return (
|
||||
<div
|
||||
id={targetId}
|
||||
className={classNames(componentName)}
|
||||
ref={listRef}
|
||||
style={{
|
||||
height,
|
||||
overflow: 'auto',
|
||||
padding: 12
|
||||
}}
|
||||
>
|
||||
{/* {loading ? (
|
||||
<p>加载中...</p>
|
||||
) : (
|
||||
<Flex wrap='wrap' gap="small" className={classNames(componentName + 'items')}>
|
||||
{data?.list?.map((item) => (
|
||||
itemRender?.(item) || (
|
||||
<div className={classNames(componentName + 'items-item')}>
|
||||
<SearchCard data={item} />
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
</Flex>
|
||||
)} */}
|
||||
<InfiniteScroll
|
||||
dataLength={data.length}
|
||||
next={type === 'auto' ? loadMore! : () => {}}
|
||||
hasMore={hasMore}
|
||||
loader={loadingMessage}
|
||||
endMessage={endMessage}
|
||||
scrollableTarget={targetId}
|
||||
>
|
||||
<Flex wrap='wrap' gap="small" className={classNames(componentName + 'items')}>
|
||||
{data?.map((item) => (
|
||||
itemRender?.(item) || (
|
||||
<div
|
||||
key={item.key || item.id}
|
||||
className={classNames(componentName + 'items-item')}
|
||||
onClick={(e) => {
|
||||
onItemClick?.(item)
|
||||
}}
|
||||
>
|
||||
<SearchCard
|
||||
data={item}
|
||||
{...searchCardProps}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
</Flex>
|
||||
</InfiniteScroll>
|
||||
{/* <div style={{ marginTop: 8 }}>
|
||||
{!noMore && (
|
||||
<Button onClick={loadMore} disabled={loadingMore}>
|
||||
{loadingMore ? '加载中...' : '点击加载更多'}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{noMore && <span>没有更多数据了</span>}
|
||||
</div> */}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
export default InfiniteList
|
94
packages/biz/src/infiniteList/components/SearchCard.tsx
Normal file
94
packages/biz/src/infiniteList/components/SearchCard.tsx
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Created by jiangzhixiong on 2024/04/28
|
||||
*/
|
||||
|
||||
import React, { forwardRef, useContext, useImperativeHandle } from 'react'
|
||||
import { ConfigProvider, EMPTY_BASE64 } from '@zhst/meta'
|
||||
import { Flex, Image } from 'antd';
|
||||
import './index.less'
|
||||
|
||||
const { ConfigContext } = ConfigProvider
|
||||
|
||||
export interface SearchCardProps {
|
||||
prefixCls?: string;
|
||||
id?: string;
|
||||
key?: string;
|
||||
url?: string;
|
||||
data?: {
|
||||
key?: string;
|
||||
url?: string;
|
||||
sort?: number;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
}
|
||||
onCreateTxt?: string;
|
||||
onCreate?: (data: any) => void;
|
||||
onAddTxt?: string;
|
||||
onAdd?: (data: any) => void;
|
||||
onRemoveTxt?: string;
|
||||
onRemove?: (data: any) => void;
|
||||
customOptionRender?: React.ReactNode
|
||||
}
|
||||
|
||||
export interface SearchCardRefProps {
|
||||
}
|
||||
|
||||
const SearchCard = forwardRef<SearchCardRefProps, SearchCardProps>((props, ref) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
url,
|
||||
id,
|
||||
key,
|
||||
data,
|
||||
onCreate,
|
||||
onCreateTxt = '创建检索',
|
||||
onAddTxt = '添加目标',
|
||||
onRemoveTxt = '移除轨迹',
|
||||
onAdd,
|
||||
onRemove,
|
||||
customOptionRender
|
||||
} = props
|
||||
const { getPrefixCls } = useContext(ConfigContext)
|
||||
const componentName = getPrefixCls('biz-search-card', customizePrefixCls);
|
||||
|
||||
const stopBumble = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>, fn: ((data: any) => void) | undefined, data: { url?: string | undefined; key?: string | undefined; title?: string | undefined; subtitle?: string | undefined; } | undefined) => {
|
||||
e.stopPropagation()
|
||||
fn?.(data)
|
||||
}
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
|
||||
}))
|
||||
|
||||
return (
|
||||
<div className={componentName} key={id || key}>
|
||||
<div className={`${componentName}-main`}>
|
||||
<i className={`${componentName}-main-num`}>-</i>
|
||||
<Image
|
||||
src={url}
|
||||
preview={false}
|
||||
width={'100%'}
|
||||
height={'240px'}
|
||||
fallback={EMPTY_BASE64}
|
||||
/>
|
||||
<Flex align='center' justify='space-between' className={`${componentName}-main-opt`}>
|
||||
{customOptionRender || (
|
||||
<>
|
||||
<a onClick={(e) => stopBumble(e, onCreate, data)}>{onCreateTxt}</a>
|
||||
|
|
||||
<a onClick={(e) => stopBumble(e, onAdd, data)}>{onAddTxt}</a>
|
||||
|
|
||||
<a onClick={(e) => stopBumble(e, onRemove, data)}>{onRemoveTxt}</a>
|
||||
</>
|
||||
)}
|
||||
</Flex>
|
||||
</div>
|
||||
<div className={`${componentName}-footer`}>
|
||||
<p className={`${componentName}-footer-tit`}>04/28 08:21:58</p>
|
||||
<p className={`${componentName}-footer-subtitle`}>西2-1</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
export default SearchCard
|
75
packages/biz/src/infiniteList/components/index.less
Normal file
75
packages/biz/src/infiniteList/components/index.less
Normal file
@ -0,0 +1,75 @@
|
||||
.zhst-biz-search-card {
|
||||
border: 2px solid transparent;
|
||||
transition: .1s ease-in all;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
border: 2px solid #09f;
|
||||
|
||||
.zhst-biz-search-card-main-opt {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
&-main {
|
||||
position: relative;
|
||||
width: 184px;
|
||||
height: 240px;
|
||||
|
||||
&-num {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
top: 2px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
color: rgb(153, 153, 153);
|
||||
background-color: rgba(255, 255, 255, 75%);
|
||||
z-index: 1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
&-opt {
|
||||
display: none;
|
||||
position: absolute;
|
||||
padding: 6px 3px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
font-size: 12px;
|
||||
background-color: #09f;
|
||||
color: #fff;
|
||||
box-sizing: border-box;
|
||||
transition: .2s ease-in all;
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
padding: 12px;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
|
||||
&-tit {
|
||||
margin: 0;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
&-subtitle {
|
||||
margin: 0;
|
||||
line-height: 20px;
|
||||
transition: .1s ease-in all;
|
||||
|
||||
&:hover {
|
||||
color: #09f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
6
packages/biz/src/infiniteList/components/index.tsx
Normal file
6
packages/biz/src/infiniteList/components/index.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Created by jiangzhixiong on 2024/04/28
|
||||
*/
|
||||
|
||||
export { default as SearchCard } from './SearchCard'
|
||||
export type { SearchCardProps, SearchCardRefProps } from './SearchCard'
|
43
packages/biz/src/infiniteList/demo/basic.tsx
Normal file
43
packages/biz/src/infiniteList/demo/basic.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { InfiniteList } from '@zhst/biz'
|
||||
|
||||
export default () => {
|
||||
const [data, setData] = useState([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const loadMoreData = () => {
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
fetch('https://randomuser.me/api/?results=10&inc=id,key,name,gender,email,nat,picture&noinfo')
|
||||
.then((res) => res.json())
|
||||
.then((body) => {
|
||||
setData([...data, ...body.results]);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadMoreData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<InfiniteList
|
||||
loading={loading}
|
||||
loadMore={loadMoreData}
|
||||
height={300}
|
||||
hasMore={data.length < 100}
|
||||
data={data}
|
||||
onItemClick={_data => console.log('item点击:', _data)}
|
||||
searchCardProps={{
|
||||
onAdd: (_data) => console.log('新增', _data),
|
||||
onCreate: (_data) => console.log('创建', _data),
|
||||
onRemove: (_data) => console.log('删除', _data),
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
51
packages/biz/src/infiniteList/demo/custom.tsx
Normal file
51
packages/biz/src/infiniteList/demo/custom.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { InfiniteList } from '@zhst/biz'
|
||||
import { Button, Input, Space } from 'antd'
|
||||
|
||||
export default () => {
|
||||
const [data, setData] = useState([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [params, setParams] = useState({})
|
||||
|
||||
const loadMoreData = (params?: { name: string; age?: number; sex: string; tel: number }) => {
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
fetch('https://randomuser.me/api/?results=10&inc=id,key,name,gender,email,nat,picture&noinfo')
|
||||
.then((res) => res.json())
|
||||
.then((body) => {
|
||||
setData([...data, ...body.results]);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadMoreData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Space direction='vertical'>
|
||||
<Space>
|
||||
<Input placeholder='名称' onChange={(e) => setParams(pre => ({ ...pre, name: e.target.value }))} style={{ width: '120px' }} />
|
||||
<Input placeholder='年龄' onChange={(e) => setParams(pre => ({ ...pre, age: e.target.value }))} style={{ width: '120px' }} />
|
||||
<Input placeholder='性别' onChange={(e) => setParams(pre => ({ ...pre, sex: e.target.value }))} style={{ width: '120px' }} />
|
||||
<Input placeholder='手机号' onChange={(e) => setParams(pre => ({ ...pre, tel: e.target.value }))} style={{ width: '120px' }} />
|
||||
<Button onClick={() => loadMoreData(params)}>加载更多</Button>
|
||||
</Space>
|
||||
<InfiniteList
|
||||
loading={loading}
|
||||
loadMore={() => loadMoreData(params)}
|
||||
height={300}
|
||||
hasMore={data.length < 100}
|
||||
data={data}
|
||||
type="custom"
|
||||
loadingMessage={<Button onClick={() => loadMoreData(params)}>加载更多</Button>}
|
||||
onItemClick={data => console.log('item点击:', data)}
|
||||
/>
|
||||
</Space>
|
||||
)
|
||||
}
|
66
packages/biz/src/infiniteList/demo/customItem.tsx
Normal file
66
packages/biz/src/infiniteList/demo/customItem.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { InfiniteList } from '@zhst/biz'
|
||||
import { Button, Input, Space } from 'antd'
|
||||
|
||||
interface IData { name: string; age?: number; sex: string; tel: number }
|
||||
|
||||
export default () => {
|
||||
const [data, setData] = useState<any>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [params, setParams] = useState<IData>({
|
||||
name: '',
|
||||
tel: 123,
|
||||
age: 12,
|
||||
sex: '男'
|
||||
})
|
||||
|
||||
const loadMoreData = (params?: IData) => {
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
fetch('https://randomuser.me/api/?results=10&inc=id,key,name,gender,email,nat,picture&noinfo', {
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((body) => {
|
||||
setData([...data, ...body.results]);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadMoreData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Space direction='vertical'>
|
||||
<Space>
|
||||
<Input placeholder='名称' onChange={(e) => setParams(pre => ({ ...pre, name: e.target.value }))} style={{ width: '120px' }} />
|
||||
<Input placeholder='年龄' onChange={(e) => setParams(pre => ({ ...pre, age: Number(e.target.value) }))} style={{ width: '120px' }} />
|
||||
<Input placeholder='性别' onChange={(e) => setParams(pre => ({ ...pre, sex: e.target.value }))} style={{ width: '120px' }} />
|
||||
<Input placeholder='手机号' onChange={(e) => setParams(pre => ({ ...pre, tel: Number(e.target.value) }))} style={{ width: '120px' }} />
|
||||
<Button onClick={() => loadMoreData(params)}>加载更多</Button>
|
||||
</Space>
|
||||
<InfiniteList
|
||||
loading={loading}
|
||||
loadMore={() => loadMoreData(params)}
|
||||
height={300}
|
||||
hasMore={data.length < 100}
|
||||
data={data}
|
||||
type="custom"
|
||||
loadingMessage={<Button onClick={() => loadMoreData(params)}>加载更多</Button>}
|
||||
itemRender={() => {
|
||||
return (
|
||||
<div style={{ width: '200px', height: '200px', border: '1px solid #000' }}>
|
||||
自定义的子元素
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
onItemClick={data => console.log('item点击:', data)}
|
||||
/>
|
||||
</Space>
|
||||
)
|
||||
}
|
17
packages/biz/src/infiniteList/demo/mock.ts
Normal file
17
packages/biz/src/infiniteList/demo/mock.ts
Normal file
@ -0,0 +1,17 @@
|
||||
const resultData = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13'];
|
||||
|
||||
export function getLoadMoreList(nextId: string | undefined, limit: number): Promise<any> {
|
||||
let start = 0;
|
||||
const end = start + limit;
|
||||
const list = resultData.slice(start, end);
|
||||
const nId = resultData.length >= end ? resultData[end] : undefined;
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
list,
|
||||
nextId: nId,
|
||||
isNoMore: list.length > 20
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
}
|
5
packages/biz/src/infiniteList/index.less
Normal file
5
packages/biz/src/infiniteList/index.less
Normal file
@ -0,0 +1,5 @@
|
||||
.zhst-biz-infinite-list {
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
21
packages/biz/src/infiniteList/index.md
Normal file
21
packages/biz/src/infiniteList/index.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
category: Components
|
||||
title: infiniteList 无限滚动列表
|
||||
toc: content
|
||||
group:
|
||||
title: 数据展示
|
||||
---
|
||||
|
||||
无限滚动列表
|
||||
|
||||
## 代码演示
|
||||
|
||||
<code src="./demo/basic.tsx">基本用法</code>
|
||||
<code src="./demo/custom.tsx">手动触发</code>
|
||||
<code src="./demo/customItem.tsx">自定义子元素</code>
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| data | 数据源 | Array[] | [] | - |
|
5
packages/biz/src/infiniteList/index.tsx
Normal file
5
packages/biz/src/infiniteList/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import InfinityList from './InfiniteList'
|
||||
|
||||
// export { InfiniteListProps, InfiniteListRefProps } from './InfiniteList'
|
||||
|
||||
export default InfinityList
|
@ -1,5 +1,19 @@
|
||||
# @zhst/material
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 视频添加 OD 框,查看大图首次点击修复
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @zhst/meta@0.15.0
|
||||
- @zhst/biz@0.17.0
|
||||
- @zhst/func@0.10.2
|
||||
- @zhst/hooks@0.9.2
|
||||
|
||||
## 0.10.4
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@zhst/material",
|
||||
"version": "0.10.4",
|
||||
"version": "0.11.0",
|
||||
"description": "物料库",
|
||||
"keywords": [
|
||||
"business",
|
||||
|
@ -21,6 +21,9 @@ export interface Option {
|
||||
* @default: true
|
||||
*/
|
||||
scaleAble?: boolean;
|
||||
width?: number;
|
||||
height?: number;
|
||||
backgroundColor?: string;
|
||||
|
||||
/*
|
||||
* 是否允许拖拽
|
||||
@ -81,7 +84,11 @@ class Viewer {
|
||||
}
|
||||
|
||||
build() {
|
||||
const { width = 300, height = 150 } = this.options
|
||||
const canvas = document.createElement('canvas');
|
||||
|
||||
canvas.width = width || canvas.width
|
||||
canvas.height = height || canvas.height
|
||||
addClass(canvas, CLASS_CANVAS);
|
||||
this.element.appendChild(canvas);
|
||||
this.canvas = canvas;
|
||||
|
@ -102,3 +102,4 @@ export type { AppProps } from './app';
|
||||
export { default as notification } from './notification';
|
||||
export type { ArgsProps as NotificationArgsProps } from './notification';
|
||||
export { default as ButtonList } from './ButtonList'
|
||||
export * from './utils'
|
||||
|
@ -0,0 +1 @@
|
||||
export * from './constants'
|
Loading…
Reference in New Issue
Block a user