refactor: add a unified warning function

This commit is contained in:
unix
2020-03-25 02:03:17 +08:00
parent 03578c2b68
commit 269a2bfae5
10 changed files with 46 additions and 17 deletions

View File

@@ -1,6 +1,7 @@
import React, { useEffect, useMemo, useState } from 'react'
import withDefaults from '../utils/with-defaults'
import { CheckboxContext } from './checkbox-context'
import useWarning from '../utils/use-warning'
interface Props {
value: string[]
@@ -22,7 +23,7 @@ const CheckboxGroup: React.FC<React.PropsWithChildren<CheckboxGroupProps>> = Rea
const [selfVal, setSelfVal] = useState<string[]>([])
if (!value) {
value = []
console.error('[Checkbox Group]: Props "value" is required.')
useWarning('Props "value" is required.', 'Checkbox Group')
}
const updateState = (val: string, checked: boolean) => {

View File

@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react'
import { useCheckbox } from './checkbox-context'
import CheckboxGroup from './checkbox-group'
import CheckboxIcon from './checkbox.icon'
import useWarning from '../utils/use-warning'
interface CheckboxEventTarget {
checked: boolean
@@ -41,11 +42,17 @@ const Checkbox: React.FC<CheckboxProps> = React.memo(({
const isDisabled = inGroup ? disabledAll || disabled : disabled
if (inGroup && !value) {
console.error('[Checkbox]: Props "value" must be set when [Checkbox] component is in the group.')
useWarning(
'Props "value" must be set when [Checkbox] component is in the group.',
'Checkbox',
)
}
if (inGroup && checked) {
console.error('[Checkbox]: Remove props "checked" when [Checkbox] component is in the group.')
useWarning(
'Remove props "checked" when [Checkbox] component is in the group.',
'Checkbox',
)
}
if (inGroup) {

View File

@@ -3,6 +3,7 @@ import useTheme from '../styles/use-theme'
import withDefaults from '../utils/with-defaults'
import useCurrentState from '../utils/use-current-state'
import { FieldsetContext, FieldItem } from './fieldset-context'
import useWarning from '../utils/use-warning'
interface Props {
value: string
@@ -26,7 +27,7 @@ const FieldsetGroup: React.FC<React.PropsWithChildren<FieldsetGroupProps>> = Rea
const register = useCallback((newItem: FieldItem) => {
const hasItem = ref.current.find(item => item.value === newItem.value)
if (hasItem) {
console.error('[Fieldset Group]: The "value" of each "Fieldset" must be unique.')
useWarning('The "value" of each "Fieldset" must be unique.', 'Fieldset')
}
setItems([...ref.current, newItem])
}, [])

View File

@@ -6,6 +6,7 @@ import FieldsetFooter from './fieldset-footer'
import FieldsetGroup from './fieldset-group'
import { hasChild, pickChild } from '../utils/collections'
import { useFieldset } from './fieldset-context'
import useWarning from '../utils/use-warning'
interface Props {
value?: string
@@ -38,7 +39,7 @@ const Fieldset: React.FC<React.PropsWithChildren<FieldsetProps>> = React.memo(({
if (inGroup) {
if (!label) {
console.error('[Fieldset Group]: Props "label" is required when in a group.')
useWarning('Props "label" is required when in a group.', 'Fieldset Group')
}
if (!value || value === '') {
value = label

View File

@@ -4,6 +4,7 @@ import { useRadioContext } from './radio-context'
import RadioGroup from './radio-group'
import RadioDescription from './radio-description'
import { pickChild } from '../utils/collections'
import useWarning from '../utils/use-warning'
interface RadioEventTarget {
checked: boolean
@@ -43,10 +44,10 @@ const Radio: React.FC<React.PropsWithChildren<RadioProps>> = React.memo(({
if (inGroup) {
if (checked !== undefined) {
console.error('[Radio]: remove props "checked" if in the Radio.Group.')
useWarning('Remove props "checked" if in the Radio.Group.', 'Radio')
}
if (radioValue === undefined) {
console.error('[Radio]: props "value" must be deinfed if in the Radio.Group.')
useWarning('Props "value" must be deinfed if in the Radio.Group.', 'Radio')
}
useEffect(() => setSelfChecked(groupValue === radioValue), [groupValue, radioValue])
}

View File

@@ -1,6 +1,7 @@
import React, { MutableRefObject, useEffect, useState } from 'react'
import React, { MutableRefObject, useState } from 'react'
import { createPortal } from 'react-dom'
import usePortal from '../utils/use-portal'
import useResize from '../utils/use-resize'
import CSSTransition from './css-transition'
interface Props {
@@ -44,13 +45,9 @@ const Dropdown: React.FC<React.PropsWithChildren<Props>> = React.memo(({
const { top, left, right, width: nativeWidth } = getRect(parent)
setRect({ top, left, right, width: nativeWidth })
}
useEffect(() => {
updateRect()
window.addEventListener('resize', updateRect)
return () => window.removeEventListener('resize', updateRect)
}, [])
useResize(updateRect)
const clickHandler = (event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation()
event.preventDefault()

View File

@@ -1,5 +1,6 @@
import React from 'react'
import withDefaults from '../utils/with-defaults'
import useWarning from '../utils/use-warning'
interface Props {
x?: number
@@ -19,7 +20,7 @@ export type SpacerProps = Props & typeof defaultProps & React.HTMLAttributes<any
const getMargin = (num: number): string => {
if (num < 0) {
console.error('[Spacer]: "x"/"y" must be greater than or equal to 0')
useWarning('Props "x"/"y" must be greater than or equal to 0', 'Spacer')
return '0'
}
return `calc(${num * 15.25}pt + 1px * ${num - 1})`

View File

@@ -4,6 +4,7 @@ import darkTheme from '../themes/dark'
import lightTheme from '../themes/default'
import { ZeitUIThemes } from '../themes/index'
import ThemeContext from '../use-theme/theme-context'
import useWarning from '../../utils/use-warning'
type PartialTheme = Partial<ZeitUIThemes>
export type ThemeParam = PartialTheme | ((theme: PartialTheme) => PartialTheme) | undefined
@@ -17,7 +18,7 @@ const mergeTheme = (current: ZeitUIThemes, custom: ThemeParam): ZeitUIThemes =>
if (typeof custom === 'function') {
const merged = custom(current)
if (!merged || typeof merged !== 'object') {
console.error('Zeit-UI: the theme function must return object value.')
useWarning('The theme function must return object value.')
}
return merged as ZeitUIThemes
}

View File

@@ -3,6 +3,7 @@ import TabsItem from './tabs-item'
import useTheme from '../styles/use-theme'
import { TabsLabelItem, TabsConfig, TabsContext } from './tabs-context'
import useCurrentState from '../utils/use-current-state'
import useWarning from '../utils/use-warning'
interface Props {
initialValue?: string
@@ -28,7 +29,7 @@ const Tabs: React.FC<React.PropsWithChildren<TabsProps>> = ({
const register = (next: TabsLabelItem) => {
const hasItem = tabsRef.current.find(item => item.value === next.value)
if (hasItem) {
console.error('[Tabs]: The "value" of each "Tabs.Item" must be unique.')
useWarning('The "value" of each "Tabs.Item" must be unique.', 'Tabs')
}
setTabs([...tabsRef.current, next])
}

View File

@@ -0,0 +1,18 @@
const warningStack: { [key: string]: boolean } = {}
const useWarning = (message: string, component?: string) => {
const tag = component ? ` [${component}]` : ' '
const log = `[Zeit UI]${tag}: ${message}`
if (typeof console === 'undefined') return
if (warningStack[log]) return
warningStack[log] = true
if (process.env.NODE_ENV !== 'production') {
return console.error(log)
}
console.warn(log)
}
export default useWarning