mirror of
https://github.com/zhigang1992/react.git
synced 2026-03-26 06:55:07 +08:00
feat(loading): add component
This commit is contained in:
@@ -39,3 +39,4 @@ export { default as Tree } from './file-tree'
|
||||
export { default as Badge } from './badge'
|
||||
export { default as AutoComplete } from './auto-complete'
|
||||
export { default as Collapse } from './collapse'
|
||||
export { default as Loading } from './loading'
|
||||
|
||||
3
components/loading/index.ts
Normal file
3
components/loading/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import Loading from './loading'
|
||||
|
||||
export default Loading
|
||||
138
components/loading/loading.tsx
Normal file
138
components/loading/loading.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import useTheme from '../styles/use-theme'
|
||||
import withDefaults from '../utils/with-defaults'
|
||||
import { NormalSizes, NormalTypes } from 'components/utils/prop-types'
|
||||
import { ZeitUIThemesPalette } from 'components/styles/themes'
|
||||
|
||||
interface Props {
|
||||
size?: NormalSizes
|
||||
type?: NormalTypes
|
||||
color?: string
|
||||
width?: string
|
||||
height?: string
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
size: 'medium' as NormalSizes,
|
||||
type: 'default' as NormalTypes,
|
||||
}
|
||||
|
||||
export type LoadingProps = Props & typeof defaultProps & React.HTMLAttributes<any>
|
||||
|
||||
const getIconSize = (size: NormalSizes) => {
|
||||
const sizes: { [key in NormalSizes]: string } = {
|
||||
mini: '2px',
|
||||
small: '3px',
|
||||
medium: '4px',
|
||||
large: '5px',
|
||||
}
|
||||
return sizes[size]
|
||||
}
|
||||
|
||||
const getIconBgColor = (
|
||||
type: NormalTypes,
|
||||
palette: ZeitUIThemesPalette,
|
||||
color?: string,
|
||||
) => {
|
||||
const colors: { [key in NormalTypes]: string } = {
|
||||
default: palette.accents_6,
|
||||
secondary: palette.secondary,
|
||||
success: palette.success,
|
||||
warning: palette.warning,
|
||||
error: palette.error,
|
||||
}
|
||||
|
||||
return color ? color : colors[type]
|
||||
}
|
||||
|
||||
const Loading: React.FC<React.PropsWithChildren<LoadingProps>> = React.memo(({
|
||||
children, size, type, color,
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const width = useMemo(() => getIconSize(size), [size])
|
||||
const bgColor = useMemo(
|
||||
() => getIconBgColor(type, theme.palette, color),
|
||||
[type, theme.palette, color],
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="loading-container">
|
||||
|
||||
<span className="loading">
|
||||
{children && (
|
||||
<label>{children}</label>
|
||||
)}
|
||||
<i />
|
||||
<i />
|
||||
<i />
|
||||
</span>
|
||||
<style jsx>{`
|
||||
.loading-container {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-right: ${theme.layout.gapHalf};
|
||||
color: ${theme.palette.accents_5};
|
||||
}
|
||||
|
||||
label :global(*) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: transparent;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
i {
|
||||
width: ${width};
|
||||
height: ${width};
|
||||
border-radius: 50%;
|
||||
background-color: ${bgColor};
|
||||
margin: 0 1px;
|
||||
display: inline-block;
|
||||
animation: loading-blink 1.4s infinite both;
|
||||
}
|
||||
|
||||
i:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
i:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
@keyframes loading-blink {
|
||||
0% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
20% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
export default withDefaults(Loading, defaultProps)
|
||||
91
pages/docs/components/loading.mdx
Normal file
91
pages/docs/components/loading.mdx
Normal file
@@ -0,0 +1,91 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Loading, Spacer, Row } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Loading',
|
||||
description: 'Loading',
|
||||
}
|
||||
|
||||
## Loading
|
||||
|
||||
Indicate an action running in the background.
|
||||
|
||||
<Playground
|
||||
scope={{ Loading, Row, Spacer }}
|
||||
code={`
|
||||
<Row style={{ padding: '10px 0'}}>
|
||||
<Loading />
|
||||
</Row>
|
||||
`} />
|
||||
|
||||
<Playground
|
||||
title="with text"
|
||||
scope={{ Loading, Row }}
|
||||
code={`
|
||||
<Row style={{ padding: '10px 0'}}>
|
||||
<Loading>Loading</Loading>
|
||||
</Row>
|
||||
`} />
|
||||
|
||||
<Playground
|
||||
title="size"
|
||||
scope={{ Loading, Row, Spacer }}
|
||||
code={`
|
||||
<>
|
||||
<Row style={{ padding: '10px 0', width: '50px' }}>
|
||||
<Loading size="mini" />
|
||||
</Row>
|
||||
<Spacer y={.5} />
|
||||
<Row style={{ padding: '10px 0', width: '50px' }}>
|
||||
<Loading size="small" />
|
||||
</Row>
|
||||
<Spacer y={.5} />
|
||||
<Row style={{ padding: '10px 0', width: '50px' }}>
|
||||
<Loading size="medium" />
|
||||
</Row>
|
||||
<Spacer y={.5} />
|
||||
<Row style={{ padding: '10px 0', width: '50px' }}>
|
||||
<Loading size="large" />
|
||||
</Row>
|
||||
</>
|
||||
`} />
|
||||
|
||||
|
||||
<Playground
|
||||
title="type"
|
||||
scope={{ Loading, Row, Spacer }}
|
||||
code={`
|
||||
<>
|
||||
<Row style={{ padding: '10px 0', width: '50px' }}>
|
||||
<Loading type="success" />
|
||||
</Row>
|
||||
<Spacer y={.5} />
|
||||
<Row style={{ padding: '10px 0', width: '50px' }}>
|
||||
<Loading type="secondary" />
|
||||
</Row>
|
||||
<Spacer y={.5} />
|
||||
<Row style={{ padding: '10px 0', width: '50px' }}>
|
||||
<Loading type="warning" />
|
||||
</Row>
|
||||
<Spacer y={.5} />
|
||||
<Row style={{ padding: '10px 0', width: '50px' }}>
|
||||
<Loading type="error" />
|
||||
</Row>
|
||||
</>
|
||||
`} />
|
||||
|
||||
<Attributes edit="/pages/docs/components/loading.mdx">
|
||||
<Attributes.Title>Loading.Props</Attributes.Title>
|
||||
|
||||
| Attribute | Description | Type | Accepted values | Default
|
||||
| ---------- | ---------- | ---- | -------------- | ------ |
|
||||
| **type** | bg-color type | `NormalTypes` | `'default', 'secondary', 'success', 'warning', 'error'` | `default` |
|
||||
| **size** | loading size | `NormalSizes` | `'mini', 'small', 'medium', 'large'` | `medium` |
|
||||
| **color** | custom bg color | `string` | - | - |
|
||||
| **width** | custom width | `string` | - | `100%` |
|
||||
| **height** | custom height | `string` | - | `100%` |
|
||||
| ... | native props | `HTMLAttributes` | `'id', 'title', 'className', ...` | - |
|
||||
|
||||
</Attributes>
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>
|
||||
Reference in New Issue
Block a user