From 08f50e5c4fa515c4b57e58626e7ecc3e0eb91da8 Mon Sep 17 00:00:00 2001 From: unix Date: Wed, 25 Mar 2020 00:50:01 +0800 Subject: [PATCH] feat(progress): add component --- components/index.ts | 1 + components/progress/index.ts | 3 + components/progress/progress.tsx | 112 +++++++++++++++++++++++++++++ pages/docs/components/progress.mdx | 82 +++++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 components/progress/index.ts create mode 100644 components/progress/progress.tsx create mode 100644 pages/docs/components/progress.mdx diff --git a/components/index.ts b/components/index.ts index 82c68bf..608913f 100644 --- a/components/index.ts +++ b/components/index.ts @@ -34,3 +34,4 @@ export { default as Input } from './input' export { default as Radio } from './radio' export { default as Select } from './select' export { default as Tabs } from './tabs' +export { default as Progress } from './progress' diff --git a/components/progress/index.ts b/components/progress/index.ts new file mode 100644 index 0000000..c98e079 --- /dev/null +++ b/components/progress/index.ts @@ -0,0 +1,3 @@ +import Progress from './progress' + +export default Progress diff --git a/components/progress/progress.tsx b/components/progress/progress.tsx new file mode 100644 index 0000000..f3cff01 --- /dev/null +++ b/components/progress/progress.tsx @@ -0,0 +1,112 @@ +import React from 'react' +import withDefaults from '../utils/with-defaults' +import useTheme from '../styles/use-theme' +import { useProportions } from '../utils/calculations' +import { ZeitUIThemesPalette } from 'components/styles/themes' +import { NormalTypes } from 'components/utils/prop-types' + +export type ProgressColors = { + [key: number]: string +} + +interface Props { + value?: number + max?: number + fixedTop?: boolean + fixedBottom?: boolean + colors?: ProgressColors + type?: NormalTypes + className?: '' +} + +const defaultProps = { + value: 0, + max: 100, + type: 'default' as NormalTypes, + fixedTop: false, + fixedBottom: false, + className: '', +} + +export type ProgressProps = Props & typeof defaultProps & React.ProgressHTMLAttributes + +const getCurrentColor = ( + ratio: number, + palette: ZeitUIThemesPalette, + type: NormalTypes, + colors: ProgressColors = {}, +): string => { + const defaultColors: { [key in NormalTypes]: string } = { + default: palette.foreground, + success: palette.success, + secondary: palette.secondary, + warning: palette.warning, + error: palette.error, + } + const colorKeys = Object.keys(colors) + if (colorKeys.length === 0) return defaultColors[type] + + const customColorKey = colorKeys.find(key => ratio <= +key) + console.log(customColorKey) + if (!customColorKey || Number.isNaN(+customColorKey)) return defaultColors[type] + return colors[+customColorKey] +} + +const Progress: React.FC = ({ + value, max, className, type, colors, fixedTop, fixedBottom, ...props +}) => { + const theme = useTheme() + const percentValue = useProportions(value, max) + const currentColor = getCurrentColor(percentValue, theme.palette, type, colors) + const fixed = fixedTop || fixedBottom + + return ( +
+
+ + +
+ ) +} + +export default withDefaults(Progress, defaultProps) diff --git a/pages/docs/components/progress.mdx b/pages/docs/components/progress.mdx new file mode 100644 index 0000000..37d364c --- /dev/null +++ b/pages/docs/components/progress.mdx @@ -0,0 +1,82 @@ +import { Layout, Playground, Attributes } from 'lib/components' +import { Progress, Spacer, useTheme, Button } from 'components' +import { useState } from 'react' + +export const meta = { + title: 'Progress', + description: 'Progress', +} + +## Progress + +Display progress relative to a limit or related to a task. + + +`} /> + + +`} /> + + { + const theme = useTheme() + const [value, setValue] = useState(20) + const colors = { + 20: theme.palette.error, + 40: theme.palette.warning, + 60: theme.palette.success, + 80: '#000', + } + return ( + <> + + + + + + + ) +} +`} /> + + + + + + + + + + +`} /> + + +Progress.Props + +| Attribute | Description | Type | Accepted values | Default +| ---------- | ---------- | ---- | -------------- | ------ | +| **value** | current value | `number` | - | 0 | +| **max** | max value | `number` | - | 100 | +| **fixedTop** | fix progress to top | `boolean` | - | `false` | +| **fixedBottom** | fix progress to bottom | `boolean` | - | `false` | +| **colors** | custom colors | `{ [key: number]: string }` | - | - | +| **type** | predefined state types | `NormalTypes` | `'default', 'secondary', 'success', 'warning', 'error'` | `default` | +| ... | native props | `ProgressHTMLAttributes` | `'aria-busy', 'className', ...` | - | + + + +export default ({ children }) => {children}