diff --git a/.eslintrc.cjs b/.eslintrc.cjs
deleted file mode 100644
index 28e6f0ea..00000000
--- a/.eslintrc.cjs
+++ /dev/null
@@ -1,31 +0,0 @@
-module.exports = {
- env: {
- browser: true,
- es2021: true,
- node: true,
- },
- extends: [
- 'eslint:recommended',
- 'plugin:react/recommended',
- 'plugin:@typescript-eslint/recommended',
- 'plugin:storybook/recommended',
- 'plugin:prettier/recommended',
- 'plugin:storybook/recommended',
- ],
- overrides: [],
- parser: '@typescript-eslint/parser',
- parserOptions: {
- ecmaVersion: 'latest',
- sourceType: 'module',
- },
- plugins: ['react', '@typescript-eslint', 'prettier'],
- rules: {
- 'react/react-in-jsx-scope': 0,
- '@typescript-eslint/no-explicit-any': 'off',
- },
- settings: {
- react: {
- version: 'detect',
- },
- },
-}
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index afc7e127..a01ea49e 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -6,9 +6,9 @@ name: val-design build and deploy
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
push:
- branches: ['main']
+ branches: [main]
pull_request:
- branches: ['main']
+ branches: [main]
# Allows you to run this workflow manually from the Actions tab
# workflow_dispatch:
diff --git a/.storybook/main.ts b/.storybook/main.ts
index 74b97748..fe66dd3a 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -1,4 +1,5 @@
import type { StorybookConfig } from '@storybook/react-vite'
+
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
index 36dacb96..89dd1e22 100644
--- a/.storybook/preview.ts
+++ b/.storybook/preview.ts
@@ -1,4 +1,3 @@
-import React from 'react'
import type { Preview } from '@storybook/react'
import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
@@ -7,7 +6,6 @@ import '../src/styles/index.scss'
import '../src/styles/storyfixed.scss'
-
library.add(fas)
const preview: Preview = {
@@ -35,5 +33,4 @@ const preview: Preview = {
// ),
// ]
-
export default preview
diff --git a/README.md b/README.md
index 8c0ef3ec..59ad17b3 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-
-
+
+
Welcome to val-design
val-design is a simple, lightweight React UI component library.
@@ -19,7 +19,7 @@
-
+
## Description
@@ -79,13 +79,15 @@ And import button:
```jsx
import { Button } from 'val-design'
-const App = () => (
- <>
-
- >
-)
+function App() {
+ return (
+ <>
+
+ >
+ )
+}
```
## Project Activity
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 00000000..e36acc4d
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,35 @@
+// module.exports = {
+// env: {
+// browser: true,
+// es2021: true,
+// node: true,
+// },
+// extends: [
+// 'eslint:recommended',
+// 'plugin:react/recommended',
+// 'plugin:@typescript-eslint/recommended',
+// 'plugin:storybook/recommended',
+// 'plugin:prettier/recommended',
+// 'plugin:storybook/recommended',
+// ],
+// overrides: [],
+// parser: '@typescript-eslint/parser',
+// parserOptions: {
+// ecmaVersion: 'latest',
+// sourceType: 'module',
+// },
+// plugins: ['react', '@typescript-eslint', 'prettier'],
+// rules: {
+// 'react/react-in-jsx-scope': 0,
+// '@typescript-eslint/no-explicit-any': 'off',
+// },
+// settings: {
+// react: {
+// version: 'detect',
+// },
+// },
+// }
+
+import antfu from '@antfu/eslint-config'
+
+export default antfu()
diff --git a/package.json b/package.json
index 0baae7c2..134c7d35 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,16 @@
{
"name": "val-design",
+ "type": "module",
"version": "0.0.46",
"private": false,
- "license": "MIT",
"description": "React UI component library",
"author": "Cupid Valentine",
- "type": "module",
+ "license": "MIT",
+ "homepage": "https://valcosmos.github.io/val-design",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/valcosmos/val-design.git"
+ },
"keywords": [
"val-design",
"front-end",
@@ -17,23 +22,18 @@
"TypeScript",
"React Hooks"
],
- "homepage": "https://valcosmos.github.io/val-design",
- "repository": {
- "type": "git",
- "url": "https://github.com/valcosmos/val-design.git"
- },
- "files": [
- "dist"
- ],
"main": "dist/index.es.js",
"module": "dist/index.es.js",
- "types": "dist/index.d.ts",
"unpkg": "dist/index.umd.js",
+ "types": "dist/index.d.ts",
+ "files": [
+ "dist"
+ ],
"scripts": {
"dev": "vite",
"preview": "vite preview",
- "lint": "eslint --ext js,ts,tsx src",
- "lint:fix": "eslint --fix --ext js,ts,tsx src --max-warnings 5",
+ "lint": "eslint .",
+ "lint:fix": "eslint . --fix",
"format": "prettier --check .",
"format:fix": "prettier --write .",
"build-ts": "tsc -p tsconfig.build.json",
@@ -51,12 +51,12 @@
"build-storybook": "storybook build"
},
"dependencies": {
- "@fortawesome/fontawesome-svg-core": "^6.5.1",
- "@fortawesome/free-solid-svg-icons": "^6.5.1",
+ "@fortawesome/fontawesome-svg-core": "^6.5.2",
+ "@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@react-spring/web": "^9.7.3",
"async-validator": "^4.2.5",
- "axios": "^1.6.7",
+ "axios": "^1.6.8",
"classnames": "^2.5.1",
"dayjs": "^1.11.10",
"lodash-es": "^4.17.21",
@@ -66,62 +66,63 @@
"uuid": "^9.0.1"
},
"devDependencies": {
- "@commitlint/cli": "^18.6.0",
- "@commitlint/config-conventional": "^18.6.0",
+ "@antfu/eslint-config": "^2.13.3",
+ "@commitlint/cli": "^19.2.2",
+ "@commitlint/config-conventional": "^19.2.2",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-terser": "^0.4.4",
- "@storybook/addon-essentials": "^7.6.13",
- "@storybook/addon-interactions": "^7.6.13",
- "@storybook/addon-links": "^7.6.13",
- "@storybook/blocks": "^7.6.13",
- "@storybook/react": "^7.6.13",
- "@storybook/react-vite": "^7.6.13",
+ "@storybook/addon-essentials": "^8.0.8",
+ "@storybook/addon-interactions": "^8.0.8",
+ "@storybook/addon-links": "^8.0.8",
+ "@storybook/blocks": "^8.0.8",
+ "@storybook/react": "^8.0.8",
+ "@storybook/react-vite": "^8.0.8",
"@storybook/testing-library": "^0.2.2",
"@testing-library/jest-dom": "^6.4.2",
- "@testing-library/react": "^14.2.1",
+ "@testing-library/react": "^15.0.2",
"@types/fs-extra": "^11.0.4",
"@types/lodash-es": "^4.17.12",
- "@types/react-dom": "^18.2.18",
+ "@types/react-dom": "^18.2.25",
"@types/react-transition-group": "^4.4.10",
"@types/uuid": "^9.0.8",
- "@typescript-eslint/eslint-plugin": "^6.21.0",
- "@typescript-eslint/parser": "^6.21.0",
+ "@typescript-eslint/eslint-plugin": "^7.6.0",
+ "@typescript-eslint/parser": "^7.6.0",
"@vitejs/plugin-react": "^4.2.1",
"@vitejs/plugin-react-swc": "^3.6.0",
"@vitest/coverage-c8": "^0.33.0",
"babel-loader": "^9.1.3",
"child_process": "^1.0.2",
"dirname-filename-esm": "^1.1.1",
- "eslint": "^8.56.0",
+ "eslint": "^9.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.29.1",
- "eslint-plugin-n": "^16.6.2",
+ "eslint-plugin-n": "^17.2.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-promise": "^6.1.1",
- "eslint-plugin-react": "^7.33.2",
+ "eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
- "eslint-plugin-storybook": "^0.6.15",
+ "eslint-plugin-storybook": "^0.8.0",
"fs-extra": "^11.2.0",
"handlebars": "^4.7.8",
- "husky": "^9.0.10",
+ "husky": "^9.0.11",
"jsdom": "^24.0.0",
"path-exists": "^5.0.0",
"prettier": "^3.2.5",
"prop-types": "^15.8.1",
"rimraf": "^5.0.5",
- "rollup": "^4.9.6",
+ "rollup": "^4.14.3",
"rollup-plugin-exclude-dependencies-from-bundle": "^1.1.23",
"rollup-plugin-sass": "^1.12.21",
"rollup-plugin-typescript2": "^0.36.0",
- "sass": "^1.70.0",
- "storybook": "^7.6.13",
+ "sass": "^1.75.0",
+ "storybook": "^8.0.8",
"ts-node": "^10.9.2",
- "typescript": "^5.3.3",
- "vite": "^5.0.12",
- "vitest": "^1.2.2"
+ "typescript": "^5.4.5",
+ "vite": "^5.2.8",
+ "vitest": "^1.5.0"
}
}
diff --git a/rollup.esm.config.js b/rollup.esm.config.js
index b0eb28f2..a8a74e3c 100644
--- a/rollup.esm.config.js
+++ b/rollup.esm.config.js
@@ -1,5 +1,5 @@
-import baseConfig from './rollup.config'
import excludeDependenciesFromBundle from 'rollup-plugin-exclude-dependencies-from-bundle'
+import baseConfig from './rollup.config'
const config = {
...baseConfig,
diff --git a/rollup.umd.config.js b/rollup.umd.config.js
index b2b009eb..70d9c20e 100644
--- a/rollup.umd.config.js
+++ b/rollup.umd.config.js
@@ -4,9 +4,9 @@
// import json from '@rollup/plugin-json'
// import sass from 'rollup-plugin-sass'
// // import excludeDependenciesFromBundle from 'rollup-plugin-exclude-dependencies-from-bundle'
-import baseConfig from './rollup.config'
import replace from '@rollup/plugin-replace'
-import terser from '@rollup/plugin-terser'
+import terser from '@rollup/plugin-terser'
+import baseConfig from './rollup.config'
// const overrides = {
// compilerOptions: {
@@ -27,16 +27,16 @@ const config = {
exports: 'named',
// 设置排除的包在cdn引入时的全局变量名
globals: {
- react: 'React',
+ 'react': 'React',
'react-dom': 'ReactDOM',
- axios: 'Axios',
+ 'axios': 'Axios',
},
plugins: [terser()],
},
],
plugins: [
replace({
- preventAssignment: true,
+ 'preventAssignment': true,
'process.env.NODE_ENV': JSON.stringify('production'),
}),
...baseConfig.plugins,
diff --git a/scripts/create.ts b/scripts/create.ts
index ef16e4e9..bd48b0e9 100644
--- a/scripts/create.ts
+++ b/scripts/create.ts
@@ -7,10 +7,11 @@
// const fetch = require('node-fetch')
import path from 'node:path'
+import { spawn } from 'node:child_process'
+import process from 'node:process'
import glob from 'glob'
import fs from 'fs-extra'
import chalk from 'chalk'
-import { spawn } from 'child_process'
import handlebars from 'handlebars'
import { pathExistsSync } from 'path-exists'
@@ -21,8 +22,9 @@ const __dirname = dirname(import.meta)
* abc-xyz => AbcXyz
* @param {*} str
*/
-const varCase = (str: string) =>
- str.replace(/-[a-z]/g, m => m[1].toUpperCase()).replace(/^.{1}/, m => m.toUpperCase())
+function varCase(str: string) {
+ return str.replace(/-[a-z]/g, m => m[1].toUpperCase()).replace(/^.{1}/, m => m.toUpperCase())
+}
const lowCase = (str: string) => str.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`).replace(/^-/, '')
async function create() {
@@ -41,7 +43,7 @@ async function create() {
const tplFiles = glob.sync(path.join(__dirname, 'template/*.hbs'))
- tplFiles.forEach(async filePath => {
+ tplFiles.forEach(async (filePath) => {
const content = await fs.readFile(filePath, 'utf-8')
const template = handlebars.compile(content)
const result = template({
diff --git a/src/App.tsx b/src/App.tsx
index 98eb9301..4880bdf2 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -12,11 +12,17 @@ function App() {
Hello Vite + React!
- Edit App.tsx
and save to test HMR updates.
+ Edit
+ {' '}
+ App.tsx
+ {' '}
+ and save to test HMR updates.
{
}
})
-test('Alert component should work', () => {
+it('alert component should work', () => {
const { getByText } = render()
const element = getByText('alert')
expect(element).toBeInTheDocument()
expect(element.className.includes('v-alert')).toBe(true)
})
-test('Alert can be closed', () => {
+it('alert can be closed', () => {
const onAlertClose = vi.fn()
const { getByText } = render()
const alert = getByText('alert')
@@ -25,8 +25,8 @@ test('Alert can be closed', () => {
expect(onAlertClose).toHaveBeenCalled()
})
-test('Alert type should work', () => {
- const { getByText } = render()
+it('alert type should work', () => {
+ const { getByText } = render()
const alert = getByText('alert')
expect(alert).toBeInTheDocument()
expect(alert.parentElement).toHaveClass('v-alert-success')
diff --git a/src/components/Alert/alert.tsx b/src/components/Alert/alert.tsx
index 2f8b6a0a..c9d290f0 100644
--- a/src/components/Alert/alert.tsx
+++ b/src/components/Alert/alert.tsx
@@ -1,4 +1,5 @@
-import React, { FC, useState } from 'react'
+import type { FC } from 'react'
+import React, { useState } from 'react'
import classNames from 'classnames'
import Icon from '../Icon'
import Transition from '../Transition'
@@ -38,7 +39,7 @@ export interface AlertProps {
*
* ```
*/
-export const Alert: FC = props => {
+export const Alert: FC = (props) => {
const [hide, setHide] = useState(false)
const { title, description, type, onClose, closable } = props
const classes = classNames('v-alert', {
@@ -47,12 +48,10 @@ export const Alert: FC = props => {
const titleClass = classNames('v-alert-title', {
'bold-title': description,
})
- const handleClose = (e: React.MouseEvent) => {
- console.log(e)
-
- if (onClose) {
+ const handleClose = () => {
+ if (onClose)
onClose()
- }
+
setHide(true)
}
return (
diff --git a/src/components/AutoComplete/autoComplete.stories.tsx b/src/components/AutoComplete/autoComplete.stories.tsx
index f01b36d7..17d99497 100644
--- a/src/components/AutoComplete/autoComplete.stories.tsx
+++ b/src/components/AutoComplete/autoComplete.stories.tsx
@@ -1,10 +1,10 @@
import React from 'react'
-import { ComponentStory, ComponentMeta } from '@storybook/react'
+import type { ComponentMeta, ComponentStory } from '@storybook/react'
import { action } from '@storybook/addon-actions'
-import { AutoComplete } from './autoComplete'
import axios from 'axios'
+import { AutoComplete } from './autoComplete'
-const handleFetch = (query: string) => {
+function handleFetch(query: string) {
// return arr.filter((item) => parseInt(item) > parseInt(query))
return axios
.get(`https://api.github.com/search/users?q=${query}`)
diff --git a/src/components/AutoComplete/autoComplete.tsx b/src/components/AutoComplete/autoComplete.tsx
index 2b43c249..2a32fbc2 100644
--- a/src/components/AutoComplete/autoComplete.tsx
+++ b/src/components/AutoComplete/autoComplete.tsx
@@ -1,25 +1,23 @@
-import React, {
+import type {
ChangeEvent,
FC,
- ReactElement,
- useEffect,
- useState,
KeyboardEvent,
- useRef,
+ ReactElement,
} from 'react'
+import React, { useEffect, useRef, useState } from 'react'
+import classNames from 'classnames'
import Icon from '../Icon'
import Transition from '../Transition'
-import Input, { InputProps } from '../Input'
+import type { InputProps } from '../Input'
+import Input from '../Input'
import { useDebounce } from '../../hooks/useDebounce'
import { useClickOutside } from '../../hooks/useClickOutside'
-import classNames from 'classnames'
-
/**
* 用于处理复杂数据结构 eg:{value:'11', key:'22'}
* 用户可自定义
@@ -59,7 +57,7 @@ export interface AutoCompleteProps extends Omit {
*
* ```
*/
-export const AutoComplete: FC = props => {
+export const AutoComplete: FC = (props) => {
const { fetchSuggestions, onSelect, value, renderOptions, ...restProps } = props
// 输入的搜索关键字
const [inputValue, setInputValue] = useState((value as string) || '')
@@ -88,18 +86,19 @@ export const AutoComplete: FC = props => {
const results = fetchSuggestions(debouncedValue)
if (results instanceof Promise) {
setLoading(true)
- results.then(data => {
+ results.then((data) => {
setSuggestions(data)
setLoading(false)
- if (data.length > 0) {
+ if (data.length > 0)
setShowDropdown(true)
- }
})
- } else {
+ }
+ else {
setSuggestions(results)
setShowDropdown(true)
}
- } else {
+ }
+ else {
setSuggestions([])
setShowDropdown(false)
}
@@ -117,16 +116,17 @@ export const AutoComplete: FC = props => {
const handleSelect = (item: DataSourceType) => {
setInputValue(item.value)
setSuggestions([])
- if (onSelect) {
+ if (onSelect)
onSelect(item)
- }
+
triggerSearch.current = false
}
const highlight = (index: number) => {
- if (index < 0) index = 0
- if (index >= suggestions.length) {
+ if (index < 0)
+ index = 0
+ if (index >= suggestions.length)
index = suggestions.length - 1
- }
+
setHighlightIndex(index)
}
const handleKeyDown = (e: KeyboardEvent) => {
@@ -196,7 +196,8 @@ export const AutoComplete: FC = props => {
value={inputValue}
onKeyDown={handleKeyDown}
onChange={handleChange}
- >
+ >
+
{/* {loading && (
diff --git a/src/components/AutoComplete/index.tsx b/src/components/AutoComplete/index.tsx
index 0b6541ea..c2d4d6d3 100644
--- a/src/components/AutoComplete/index.tsx
+++ b/src/components/AutoComplete/index.tsx
@@ -1,2 +1,3 @@
import { AutoComplete } from './autoComplete'
+
export default AutoComplete
diff --git a/src/components/Button/button.stories.tsx b/src/components/Button/button.stories.tsx
index c1b85acf..89b04afe 100644
--- a/src/components/Button/button.stories.tsx
+++ b/src/components/Button/button.stories.tsx
@@ -1,5 +1,5 @@
import React from 'react'
-import { Meta, StoryFn } from '@storybook/react'
+import type { Meta, StoryFn } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import { Button } from './button'
diff --git a/src/components/Button/button.test.tsx b/src/components/Button/button.test.tsx
index b17fe748..aa9ee452 100644
--- a/src/components/Button/button.test.tsx
+++ b/src/components/Button/button.test.tsx
@@ -1,7 +1,7 @@
import { fireEvent, render } from '@testing-library/react'
import Button from './index'
-test('Button component should work', () => {
+it('button component should work', () => {
const onButtonClick = vi.fn()
const { getByText } = render()
const element = getByText('button')
@@ -13,16 +13,16 @@ test('Button component should work', () => {
expect(onButtonClick).toHaveBeenCalled()
})
-test('Button type and custom class should work', () => {
+it('button type and custom class should work', () => {
const { getByRole } = render()
const button = getByRole('button')
expect(button).toBeInTheDocument()
expect(button).toHaveClass('btn-primary my-button')
})
-test('Link button should work', () => {
+it('link button should work', () => {
const { getByText } = render(
-
)
- } else {
+ }
+ else {
return (
{children}
diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx
index 34b65b47..6e408be5 100644
--- a/src/components/Button/index.tsx
+++ b/src/components/Button/index.tsx
@@ -1,2 +1,3 @@
import Button from './button'
+
export default Button
diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx
index 160f0a6b..ce55039a 100644
--- a/src/components/Calendar/Calendar.tsx
+++ b/src/components/Calendar/Calendar.tsx
@@ -1,9 +1,11 @@
-import dayjs, { Dayjs } from 'dayjs'
-import MonthCalendar from './MonthCalendar'
+import type { Dayjs } from 'dayjs'
+import dayjs from 'dayjs'
import './index.scss'
-import Header from './Header'
-import { CSSProperties, ReactNode, useState } from 'react'
+import type { CSSProperties, ReactNode } from 'react'
+import { useState } from 'react'
import cs from 'classnames'
+import MonthCalendar from './MonthCalendar'
+import Header from './Header'
import LocaleContext from './LocaleContext'
export interface CalendarProps {
diff --git a/src/components/Calendar/Header.tsx b/src/components/Calendar/Header.tsx
index 3a60ef16..b9e06493 100644
--- a/src/components/Calendar/Header.tsx
+++ b/src/components/Calendar/Header.tsx
@@ -1,7 +1,8 @@
-import { Dayjs } from 'dayjs'
+import type { Dayjs } from 'dayjs'
import { useContext } from 'react'
import LocaleContext from './LocaleContext'
import allLocales from './locale'
+
interface HeaderProps {
curMonth: Dayjs
prevMonthHandler: () => void
diff --git a/src/components/Calendar/MonthCalendar.tsx b/src/components/Calendar/MonthCalendar.tsx
index bdd3bc6d..9f8bfb7b 100644
--- a/src/components/Calendar/MonthCalendar.tsx
+++ b/src/components/Calendar/MonthCalendar.tsx
@@ -1,9 +1,9 @@
import type { Dayjs } from 'dayjs'
-import { CalendarProps } from './Calendar'
-import LocaleContext from './LocaleContext'
import { useContext } from 'react'
-import allLocales from './locale'
import cs from 'classnames'
+import type { CalendarProps } from './Calendar'
+import LocaleContext from './LocaleContext'
+import allLocales from './locale'
interface MonthCalendarProps extends CalendarProps {
selectHandler?: (date: Dayjs) => void
@@ -14,7 +14,7 @@ function getAllDays(date: Dayjs) {
const startDate = date.startOf('month')
const day = startDate.day()
- const daysInfo: Array<{ date: Dayjs; currentMonth: boolean }> = new Array(6 * 7)
+ const daysInfo: Array<{ date: Dayjs, currentMonth: boolean }> = Array.from({ length: 6 * 7 })
for (let i = 0; i < day; i++) {
daysInfo[i] = {
@@ -46,7 +46,7 @@ function MonthCalendar(props: MonthCalendarProps) {
const allDays = getAllDays(curMonth)
- function renderDays(days: Array<{ date: Dayjs; currentMonth: boolean }>) {
+ function renderDays(days: Array<{ date: Dayjs, currentMonth: boolean }>) {
const rows = []
for (let i = 0; i < 6; i++) {
const row = []
@@ -55,30 +55,32 @@ function MonthCalendar(props: MonthCalendarProps) {
row[j] = (
selectHandler?.(item.date)}
>
- {dateRender ? (
- dateRender(item.date)
- ) : (
-
-
- {item.date.date()}
-
-
- {dateInnerContent?.(item.date)}
+ {dateRender
+ ? (
+ dateRender(item.date)
+ )
+ : (
+
+
+ {item.date.date()}
+
+
+ {dateInnerContent?.(item.date)}
+
-
- )}
+ )}
)
}
diff --git a/src/components/Calendar/calendar.stories.tsx b/src/components/Calendar/calendar.stories.tsx
index b8e3372c..6a6c6663 100644
--- a/src/components/Calendar/calendar.stories.tsx
+++ b/src/components/Calendar/calendar.stories.tsx
@@ -1,8 +1,8 @@
import React from 'react'
-import { Meta, StoryFn } from '@storybook/react'
+import type { Meta, StoryFn } from '@storybook/react'
-import Calendar from '.'
import dayjs from 'dayjs'
+import Calendar from '.'
const meta = {
title: 'Data Display/Calendar 组件',
diff --git a/src/components/Calendar/locale/en-US.ts b/src/components/Calendar/locale/en-US.ts
index 12106a3d..812253de 100644
--- a/src/components/Calendar/locale/en-US.ts
+++ b/src/components/Calendar/locale/en-US.ts
@@ -1,4 +1,4 @@
-import { CalendarType } from './interface'
+import type { CalendarType } from './interface'
const CalendarLocale: CalendarType = {
formatYear: 'YYYY',
diff --git a/src/components/Calendar/locale/index.ts b/src/components/Calendar/locale/index.ts
index 48126c57..aca73a48 100644
--- a/src/components/Calendar/locale/index.ts
+++ b/src/components/Calendar/locale/index.ts
@@ -1,6 +1,6 @@
import zhCN from './zh-CN'
import enUS from './en-US'
-import { CalendarType } from './interface'
+import type { CalendarType } from './interface'
const allLocales: Record
= {
'zh-CN': zhCN,
diff --git a/src/components/Calendar/locale/zh-CN.ts b/src/components/Calendar/locale/zh-CN.ts
index e827aab0..136888ba 100644
--- a/src/components/Calendar/locale/zh-CN.ts
+++ b/src/components/Calendar/locale/zh-CN.ts
@@ -1,4 +1,4 @@
-import { CalendarType } from './interface'
+import type { CalendarType } from './interface'
const CalendarLocale: CalendarType = {
formatYear: 'YYYY 年',
diff --git a/src/components/Card/card.stories.tsx b/src/components/Card/card.stories.tsx
index fb177586..69287a0f 100644
--- a/src/components/Card/card.stories.tsx
+++ b/src/components/Card/card.stories.tsx
@@ -1,5 +1,5 @@
import React from 'react'
-import { Meta, StoryFn } from '@storybook/react'
+import type { Meta, StoryFn } from '@storybook/react'
import Card from './card'
diff --git a/src/components/Card/card.tsx b/src/components/Card/card.tsx
index f9d7e4a4..9ab92650 100644
--- a/src/components/Card/card.tsx
+++ b/src/components/Card/card.tsx
@@ -1,4 +1,5 @@
-import React, { CSSProperties, FC, ReactNode } from 'react'
+import type { CSSProperties, FC, ReactNode } from 'react'
+import React from 'react'
import classNames from 'classnames'
type ShadowType = 'never' | 'hover' | 'always'
diff --git a/src/components/Form/form.stories.tsx b/src/components/Form/form.stories.tsx
index ed18ea12..6847d120 100644
--- a/src/components/Form/form.stories.tsx
+++ b/src/components/Form/form.stories.tsx
@@ -1,12 +1,12 @@
import React, { useRef, useState } from 'react'
-import { Meta } from '@storybook/react'
-import Form from '.'
-import type { FormProps, IFormRef } from './form'
-import Item from './formItem'
+import type { Meta } from '@storybook/react'
import Input from '../Input'
import Button from '../Button'
-import { CustomRule } from './useStore'
+import type { FormProps, IFormRef } from './form'
+import Item from './formItem'
+import type { CustomRule } from './useStore'
+import Form from '.'
const meta = {
title: 'Data Entry/Form 组件',
@@ -35,12 +35,10 @@ const confirmRules: CustomRule[] = [
{ type: 'string', required: true, min: 3, max: 8 },
({ getFieldValue }) => ({
asyncValidator(rule, value) {
- console.log('the value', getFieldValue('password'))
- console.log(value)
return new Promise((resolve, reject) => {
- if (value !== getFieldValue('password')) {
- reject('The two passwords that you entered do not match!')
- }
+ if (value !== getFieldValue('password'))
+ reject(new Error('The two passwords that you entered do not match!'))
+
setTimeout(() => {
resolve()
}, 1000)
@@ -48,7 +46,7 @@ const confirmRules: CustomRule[] = [
},
}),
]
-export const ABasicForm = (args: FormProps) => {
+export function ABasicForm(args: FormProps) {
return (
- 登陆 {isSubmitting ? '验证中' : '验证完毕'} {isValid ? '通过😄' : '没通过😢'}{' '}
+ 登陆
+ {' '}
+ {isSubmitting ? '验证中' : '验证完毕'}
+ {' '}
+ {isValid ? '通过😄' : '没通过😢'}
+ {' '}
重置
diff --git a/src/components/Form/form.tsx b/src/components/Form/form.tsx
index 00c38ccc..5ddbce19 100644
--- a/src/components/Form/form.tsx
+++ b/src/components/Form/form.tsx
@@ -1,7 +1,9 @@
-import React, { createContext, FormEvent, ReactNode, forwardRef, useImperativeHandle } from 'react'
+import type { FormEvent, ReactNode } from 'react'
+import React, { createContext, forwardRef, useImperativeHandle } from 'react'
-import useStore, { FormState } from './useStore'
-import { ValidateError } from 'async-validator'
+import type { ValidateError } from 'async-validator'
+import type { FormState } from './useStore'
+import useStore from './useStore'
export type RenderProps = (form: FormState) => ReactNode
@@ -17,7 +19,7 @@ export type IFromContext = Pick<
ReturnType,
'dispatch' | 'fields' | 'validateField'
> &
- Pick
+Pick
export const FormContext = createContext({} as IFromContext)
@@ -43,19 +45,17 @@ export const Form = forwardRef((props, ref) => {
e.preventDefault()
e.stopPropagation()
const { isValid, errors, values } = await validateAllFields()
- if (isValid && onFinish) {
+ if (isValid && onFinish)
onFinish(values)
- } else if (!isValid && onFinishFailed) {
+ else if (!isValid && onFinishFailed)
onFinishFailed(values, errors)
- }
}
let childrenNode: ReactNode
- if (typeof children === 'function') {
+ if (typeof children === 'function')
childrenNode = children(form)
- } else {
+ else
childrenNode = children
- }
return (
<>
diff --git a/src/components/Form/formItem.tsx b/src/components/Form/formItem.tsx
index 88abd66e..ad6feb66 100644
--- a/src/components/Form/formItem.tsx
+++ b/src/components/Form/formItem.tsx
@@ -1,7 +1,8 @@
import classNames from 'classnames'
-import React, { FC, ReactNode, useContext, useEffect } from 'react'
+import type { FC, ReactNode } from 'react'
+import React, { useContext, useEffect } from 'react'
import { FormContext } from './form'
-import { CustomRule } from './useStore'
+import type { CustomRule } from './useStore'
export type SomeRequired = Required> & Omit
@@ -18,7 +19,7 @@ export interface FormItemProps {
validateTrigger?: string
}
-export const FormItem: FC = props => {
+export const FormItem: FC = (props) => {
const {
label,
children,
@@ -77,24 +78,24 @@ export const FormItem: FC = props => {
controlProps[valuePropName] = value
controlProps[trigger] = onValueUpdate
- if (rules) {
+ if (rules)
controlProps[validateTrigger] = onValueValidate
- }
+
// 获取children数组的第一个元素
const childList = React.Children.toArray(children)
// todo 判断children类型 显示警告
// 没有子组件
- if (childList.length === 0) {
+ if (childList.length === 0)
console.error('No child element found in Form.Item, please provide one form component')
- }
+
// 子组件大于一个
- if (childList.length > 1) {
+ if (childList.length > 1)
console.warn('Only support one child element in Form.Item, others will be omitted')
- }
+
// 不是 React Element的子组件
- if (!React.isValidElement(childList[0])) {
+ if (!React.isValidElement(childList[0]))
console.error('Child component is not a valid React Element')
- }
+
const child = childList[0] as React.ReactElement
// clone Element 混合child 以及手动的属性列表
const returnChildNode = React.cloneElement(child, {
diff --git a/src/components/Form/index.tsx b/src/components/Form/index.tsx
index 8b34dc99..74edfdfd 100644
--- a/src/components/Form/index.tsx
+++ b/src/components/Form/index.tsx
@@ -1,6 +1,7 @@
-import { FC } from 'react'
+import type { FC } from 'react'
import Form from './form'
-import FormItem, { FormItemProps } from './formItem'
+import type { FormItemProps } from './formItem'
+import FormItem from './formItem'
export type IFormComponent = typeof Form & {
Item: FC
diff --git a/src/components/Form/useStore.tsx b/src/components/Form/useStore.tsx
index 4d13b416..7ce523b2 100644
--- a/src/components/Form/useStore.tsx
+++ b/src/components/Form/useStore.tsx
@@ -1,6 +1,7 @@
import { useReducer, useState } from 'react'
-import Schema, { RuleItem, ValidateError } from 'async-validator'
-import { mapValues, each } from 'lodash-es'
+import type { RuleItem, ValidateError } from 'async-validator'
+import Schema from 'async-validator'
+import { each, mapValues } from 'lodash-es'
export type CustomRuleFunc = ({
getFieldValue,
@@ -76,16 +77,16 @@ function useStore(initialValues?: Record) {
fields[name] && dispatch({ type: 'updateValue', name, value })
const resetFields = () =>
- initialValues &&
- each(initialValues, (value, name) => {
- if (fields[name]) {
+ initialValues
+ && each(initialValues, (value, name) => {
+ if (fields[name])
dispatch({ type: 'updateValue', name, value })
- }
})
const transformRules = (rules: CustomRule[]) =>
- rules.map(rule => {
- if (typeof rule === 'function') return rule({ getFieldValue })
+ rules.map((rule) => {
+ if (typeof rule === 'function')
+ return rule({ getFieldValue })
return rule
})
@@ -104,15 +105,14 @@ function useStore(initialValues?: Record) {
try {
await validator.validate(valueMap)
- } catch (e) {
+ }
+ catch (e) {
isValid = false
const err = e as any
- console.log('e', err.errors)
- console.log('fields', err.fields)
errors = err.errors
- } finally {
- console.log('errors', isValid)
+ }
+ finally {
dispatch({
type: 'updateValidateResult',
name,
@@ -130,7 +130,8 @@ function useStore(initialValues?: Record) {
setForm({ ...form, isSubmitting: true })
try {
await validator.validate(valueMap)
- } catch (e) {
+ }
+ catch (e) {
isValid = false
const err = e as ValidateErrorType
errors = err.fields
@@ -143,7 +144,8 @@ function useStore(initialValues?: Record) {
name,
value: { isValid: false, errors: itemErrors },
})
- } else if (value.rules.length > 0 && !errors[name]) {
+ }
+ else if (value.rules.length > 0 && !errors[name]) {
// 有对应的rules 并且没有errors
dispatch({
@@ -153,7 +155,8 @@ function useStore(initialValues?: Record) {
})
}
})
- } finally {
+ }
+ finally {
setForm({ ...form, isSubmitting: false, isValid, errors })
// eslint-disable-next-line no-unsafe-finally
return { isValid, errors, values: valueMap }
diff --git a/src/components/Icon/icon.stories.tsx b/src/components/Icon/icon.stories.tsx
index 8031ef38..1bb47a80 100644
--- a/src/components/Icon/icon.stories.tsx
+++ b/src/components/Icon/icon.stories.tsx
@@ -1,5 +1,5 @@
import React from 'react'
-import { Meta, StoryFn } from '@storybook/react'
+import type { Meta, StoryFn } from '@storybook/react'
import Icon from './icon'
const meta = {
diff --git a/src/components/Icon/icon.tsx b/src/components/Icon/icon.tsx
index 6273476b..f81f9870 100644
--- a/src/components/Icon/icon.tsx
+++ b/src/components/Icon/icon.tsx
@@ -1,6 +1,8 @@
-import React, { FC } from 'react'
+import type { FC } from 'react'
+import React from 'react'
import classNames from 'classnames'
-import { FontAwesomeIcon, FontAwesomeIconProps } from '@fortawesome/react-fontawesome'
+import type { FontAwesomeIconProps } from '@fortawesome/react-fontawesome'
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
export type ThemeProps =
| 'primary'
@@ -46,7 +48,7 @@ export interface IconProps extends FontAwesomeIconProps {
*
* ```
*/
-export const Icon: FC = props => {
+export const Icon: FC = (props) => {
// icon-primary
const { className, theme, ...restProps } = props
const classes = classNames('v-icon', className, {
diff --git a/src/components/Input/index.tsx b/src/components/Input/index.tsx
index f9e90da1..7e86fd68 100644
--- a/src/components/Input/index.tsx
+++ b/src/components/Input/index.tsx
@@ -1,3 +1,5 @@
-import Input, { InputProps } from './input'
+import type { InputProps } from './input'
+import Input from './input'
+
export type { InputProps }
export default Input
diff --git a/src/components/Input/input.stories.tsx b/src/components/Input/input.stories.tsx
index e1f8c42a..dd664b6b 100644
--- a/src/components/Input/input.stories.tsx
+++ b/src/components/Input/input.stories.tsx
@@ -1,5 +1,5 @@
import React from 'react'
-import { Meta, StoryFn } from '@storybook/react'
+import type { Meta, StoryFn } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import { Input } from './input'
diff --git a/src/components/Input/input.tsx b/src/components/Input/input.tsx
index 7011fccd..6e544721 100644
--- a/src/components/Input/input.tsx
+++ b/src/components/Input/input.tsx
@@ -1,6 +1,7 @@
-import React, { FC, ReactElement, InputHTMLAttributes, ChangeEvent } from 'react'
+import type { ChangeEvent, FC, InputHTMLAttributes, ReactElement } from 'react'
+import React from 'react'
import classNames from 'classnames'
-import { IconProp } from '@fortawesome/fontawesome-svg-core'
+import type { IconProp } from '@fortawesome/fontawesome-svg-core'
import Icon from '../Icon/icon'
type InputSize = 'lg' | 'sm'
@@ -39,7 +40,7 @@ export interface InputProps extends Omit, 'size
*
* ```
*/
-export const Input: FC = props => {
+export const Input: FC = (props) => {
const { disabled, size, icon, prepend, append, style, ...restProps } = props
const cnames = classNames('v-input-wrapper', {
[`input-size-${size}`]: size,
diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx
index 36324490..b71b1417 100644
--- a/src/components/Menu/index.tsx
+++ b/src/components/Menu/index.tsx
@@ -1,7 +1,11 @@
-import Menu, { MenuProps } from './menu'
-import SubMenu, { SubMenuProps } from './subMenu'
-import MenuItem, { MenuItemProps } from './menuItem'
-import { FC } from 'react'
+import type { FC } from 'react'
+import type { MenuProps } from './menu'
+import Menu from './menu'
+import type { SubMenuProps } from './subMenu'
+import SubMenu from './subMenu'
+import type { MenuItemProps } from './menuItem'
+import MenuItem from './menuItem'
+
export type IMenuComponent = FC & {
Item: FC
SubMenu: FC
diff --git a/src/components/Menu/menu.stories.tsx b/src/components/Menu/menu.stories.tsx
index a347c767..245180cc 100644
--- a/src/components/Menu/menu.stories.tsx
+++ b/src/components/Menu/menu.stories.tsx
@@ -1,8 +1,8 @@
import React from 'react'
-import { Meta, StoryFn } from '@storybook/react'
-import Menu from './index'
+import type { Meta, StoryFn } from '@storybook/react'
import { action } from '@storybook/addon-actions'
+import Menu from './index'
const meta = {
title: 'Data Entry/Menu 导航菜单',
@@ -12,7 +12,7 @@ const meta = {
export default meta
export const HorizontalMenu: StoryFn = args => (
-