├── src
├── hooks
│ ├── README.md
│ └── useConsole
│ │ ├── index.ts
│ │ └── demos
│ │ └── demo1.tsx
├── components
│ ├── README.md
│ └── Button
│ │ ├── index.tsx
│ │ └── demos
│ │ └── demo1.tsx
├── vite.env.d.ts
└── index.ts
├── .husky
├── pre-commit
└── commit-msg
├── .npmrc
├── .github
└── FUNDING.yml
├── eslint.config.ts
├── docs
└── pages
│ ├── $.mdx
│ ├── global.css
│ ├── 404.tsx
│ └── _theme.tsx
├── postcss.config.js
├── vercel.json
├── .editorconfig
├── test
└── components
│ ├── __snapshots__
│ └── button.spec.tsx.snap
│ └── button.spec.tsx
├── tailwind.config.ts
├── .changeset
├── config.json
└── README.md
├── index.html
├── tsconfig.node.json
├── .gitignore
├── vite.base.config.ts
├── tsconfig.json
├── README.md
├── LICENSE
├── vite.lib.config.ts
├── auto-imports.d.ts
├── .vscode
└── settings.json
├── vite.docs.config.ts
├── package.json
└── commitlint.config.ts
/src/hooks/README.md:
--------------------------------------------------------------------------------
1 | # Hooks
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | npx --no -- lint-staged
--------------------------------------------------------------------------------
/src/components/README.md:
--------------------------------------------------------------------------------
1 | # Components
2 |
--------------------------------------------------------------------------------
/src/vite.env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist = true
2 | enable-pre-post-scripts = true
3 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | open_collective: yuns
2 | custom: ['https://afdian.net/@yunslove']
3 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | npx --no -- commitlint --edit $1
2 | npx --no -- @jannajs/lint emojify $1
--------------------------------------------------------------------------------
/eslint.config.ts:
--------------------------------------------------------------------------------
1 | import janna from '@jannajs/lint/eslint'
2 |
3 | export default janna()
4 |
--------------------------------------------------------------------------------
/docs/pages/$.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | ---
4 |
5 | import README from '../../README.md'
6 |
7 |
8 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Button } from '@/components/Button'
2 | export { default as useConsole } from '@/hooks/useConsole'
3 |
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://openapi.vercel.sh/vercel.json",
3 | "installCommand": "pnpm i",
4 | "buildCommand": "npm run ssg",
5 | "outputDirectory": "dist-docs"
6 | }
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # https://editorconfig.org/
2 | root = true
3 |
4 | [*]
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 2
9 | charset = utf-8
10 |
--------------------------------------------------------------------------------
/test/components/__snapshots__/button.spec.tsx.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`link changes the class when hovered 1`] = `
4 |
9 | `;
10 |
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from 'tailwindcss'
2 |
3 | const config = {
4 | content: ['./src/**/*.{ts,tsx,mdx}', './docs/**/*.{ts,tsx,mdx}'],
5 | theme: {
6 | extend: {},
7 | },
8 | plugins: [],
9 | } satisfies Config
10 |
11 | export default config
12 |
--------------------------------------------------------------------------------
/src/hooks/useConsole/index.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import { useEffect } from 'react'
3 |
4 | export default function useConsole() {
5 | useEffect(() => {
6 | console.log('onMount')
7 |
8 | return () => {
9 | console.log('onUnmount')
10 | }
11 | }, [])
12 | }
13 |
--------------------------------------------------------------------------------
/src/hooks/useConsole/demos/demo1.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @title useConsole
3 | * @description useConsole description
4 | */
5 |
6 | import { useConsole } from 'pkg-name'
7 | import React from 'react'
8 |
9 | export default function Demo() {
10 | useConsole()
11 | return
demo: useConsole
12 | }
13 |
--------------------------------------------------------------------------------
/docs/pages/global.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | .vp-local-navCtn svg {
6 | display: inline;
7 | vertical-align: unset;
8 | }
9 |
10 | .markdown-body li {
11 | list-style: disc;
12 | }
13 |
14 | .markdown-body img {
15 | display: inline-block;
16 | }
17 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
3 | "changelog": "@changesets/cli/changelog",
4 | "commit": false,
5 | "fixed": [],
6 | "linked": [],
7 | "access": "restricted",
8 | "baseBranch": "master",
9 | "updateInternalDependencies": "patch",
10 | "ignore": []
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/Button/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export interface IButtonProps
4 | extends React.ButtonHTMLAttributes {}
5 |
6 | export default function Button(props: IButtonProps) {
7 | const { children, ...rest } = props
8 |
9 | return
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Button/demos/demo1.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @title Button
3 | * @description Button description
4 | */
5 |
6 | import { Button } from 'pkg-name'
7 | import React from 'react'
8 |
9 | export default function Demo() {
10 | return (
11 |
12 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | pkg-name
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "resolveJsonModule": true,
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "include": [
10 | "vite.base.config.ts",
11 | "vite.lib.config.ts",
12 | "vite.docs.config.ts",
13 | "vite.config.ts",
14 | "eslint.config.ts",
15 | "package.json"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | dist-docs
14 | *.local
15 |
16 | # Editor directories and files
17 | .vscode/*
18 | !.vscode/extensions.json
19 | !.vscode/settings.json
20 | .idea
21 | .DS_Store
22 | *.suo
23 | *.ntvs*
24 | *.njsproj
25 | *.sln
26 | *.sw?
27 |
28 | # custom
29 | coverage
30 |
--------------------------------------------------------------------------------
/vite.base.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import tsconfigPaths from 'vite-tsconfig-paths'
4 | import autoImport from 'unplugin-auto-import/vite'
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [
9 | react({
10 | jsxRuntime: 'classic',
11 | }),
12 | autoImport({ imports: ['react'] }),
13 | tsconfigPaths(),
14 | ],
15 | })
16 |
--------------------------------------------------------------------------------
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets)
4 |
5 | We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
6 |
--------------------------------------------------------------------------------
/docs/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useNavigate } from 'react-router-dom'
3 |
4 | function Component404() {
5 | const navigate = useNavigate()
6 |
7 | return (
8 |
9 |
404
10 |
Page not found
11 |
20 |
21 | )
22 | }
23 |
24 | export default Component404
25 |
--------------------------------------------------------------------------------
/test/components/button.spec.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import renderer from 'react-test-renderer'
3 | import { expect, it } from 'vitest'
4 |
5 | import { Button } from '../../src'
6 |
7 | function toJson(component: renderer.ReactTestRenderer) {
8 | const result = component.toJSON()
9 | expect(result).toBeDefined()
10 | expect(result).not.toBeInstanceOf(Array)
11 | return result as renderer.ReactTestRendererJSON
12 | }
13 |
14 | it('link changes the class when hovered', () => {
15 | const component = renderer.create()
16 | const tree = toJson(component)
17 | expect(tree).toMatchSnapshot()
18 | })
19 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "jsx": "react",
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "useDefineForClassFields": true,
7 | "baseUrl": ".",
8 | "module": "ESNext",
9 | "moduleResolution": "Bundler",
10 | "paths": {
11 | "@/*": ["./src/*"],
12 | "pkg-name": ["./src"]
13 | },
14 | "resolveJsonModule": true,
15 | "allowJs": false,
16 | "strict": true,
17 | "declaration": true,
18 | "noEmit": true,
19 | "outDir": "./dist",
20 | "allowSyntheticDefaultImports": true,
21 | "esModuleInterop": false,
22 | "forceConsistentCasingInFileNames": true,
23 | "isolatedModules": true,
24 | "skipLibCheck": true
25 | },
26 | "references": [{ "path": "./tsconfig.node.json" }],
27 | "include": ["src"]
28 | }
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pkg-name
2 |
3 | [](https://www.npmjs.com/package/pkg-name)
4 |
5 | ## Usage
6 |
7 | - Search and replace all `pkg-name` to `what-you-want-package-name`
8 | - Update [\_theme.tsx](./docs/pages/_theme.tsx) package href, remove useless navs
9 | - Update or remove test cases
10 | - Add description to [package.json](./package.json)
11 | - Add some keywords to [package.json](./package.json)
12 | - Update the author information, like name, link, FUNDING etc.
13 |
14 | Finally, you can remove the [usage section](#usage) completely.
15 |
16 | ## Build & Publish
17 |
18 | - `npm run build`
19 | - `npx changeset`
20 | - `npx changeset version`
21 | - `git commit`
22 | - `npx changeset publish`
23 | - `git push --follow-tags`
24 |
25 | > [`changeset` prerelease doc](https://github.com/changesets/changesets/blob/main/docs/prereleases.md)
26 |
27 | ## License
28 |
29 | [MIT](./LICENSE) License © 2022 [Yuns](https://github.com/yunsii)
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Yuns
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/vite.lib.config.ts:
--------------------------------------------------------------------------------
1 | import path from 'node:path'
2 |
3 | import { mergeConfig } from 'vite'
4 | import dts from 'vite-plugin-dts'
5 |
6 | import baseConfig from './vite.base.config'
7 |
8 | import type { UserConfig } from 'vite'
9 |
10 | // https://vitejs.dev/config/
11 | export default mergeConfig(baseConfig, {
12 | plugins: [dts({
13 | exclude: '**/demos',
14 | })],
15 | build: {
16 | minify: false,
17 | lib: {
18 | entry: path.resolve(__dirname, 'src/index.ts'),
19 | formats: ['es'],
20 | },
21 | rollupOptions: {
22 | // inspired from: https://github.com/vitejs/vite/discussions/1736#discussioncomment-2621441
23 | // preserveModulesRoot: https://rollupjs.org/guide/en/#outputpreservemodulesroot
24 | output: {
25 | dir: 'dist',
26 | preserveModules: true,
27 | preserveModulesRoot: 'src',
28 | entryFileNames: '[name].js',
29 | },
30 | // ref: https://github.com/vitejs/vite/issues/4454#issuecomment-1407461535
31 | // eslint-disable-next-line regexp/no-unused-capturing-group
32 | external: (source, _, isResolved) => !(isResolved || /(^[./])|(^@\/)/.test(source)),
33 | },
34 | target: 'esnext',
35 | },
36 | } as UserConfig)
37 |
--------------------------------------------------------------------------------
/auto-imports.d.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | /* prettier-ignore */
3 | // @ts-nocheck
4 | // noinspection JSUnusedGlobalSymbols
5 | // Generated by unplugin-auto-import
6 | export {}
7 | declare global {
8 | const createRef: typeof import('react')['createRef']
9 | const forwardRef: typeof import('react')['forwardRef']
10 | const lazy: typeof import('react')['lazy']
11 | const memo: typeof import('react')['memo']
12 | const startTransition: typeof import('react')['startTransition']
13 | const useCallback: typeof import('react')['useCallback']
14 | const useContext: typeof import('react')['useContext']
15 | const useDebugValue: typeof import('react')['useDebugValue']
16 | const useDeferredValue: typeof import('react')['useDeferredValue']
17 | const useEffect: typeof import('react')['useEffect']
18 | const useId: typeof import('react')['useId']
19 | const useImperativeHandle: typeof import('react')['useImperativeHandle']
20 | const useInsertionEffect: typeof import('react')['useInsertionEffect']
21 | const useLayoutEffect: typeof import('react')['useLayoutEffect']
22 | const useMemo: typeof import('react')['useMemo']
23 | const useReducer: typeof import('react')['useReducer']
24 | const useRef: typeof import('react')['useRef']
25 | const useState: typeof import('react')['useState']
26 | const useSyncExternalStore: typeof import('react')['useSyncExternalStore']
27 | const useTransition: typeof import('react')['useTransition']
28 | }
29 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "eslint.options": {
4 | "flags": ["unstable_ts_config"]
5 | },
6 |
7 | // Disable the default formatter, use eslint instead
8 | "prettier.enable": false,
9 | "editor.formatOnSave": false,
10 |
11 | // Auto fix
12 | "editor.codeActionsOnSave": {
13 | "source.fixAll.eslint": "explicit",
14 | "source.organizeImports": "never"
15 | },
16 |
17 | // Silent the stylistic rules in you IDE, but still auto fix them
18 | "eslint.rules.customizations": [
19 | // 存在部分暂时不能自动修复的,比如 style/max-statements-per-line
20 | // { "rule": "style/*", "severity": "off" },
21 | { "rule": "format/*", "severity": "off" },
22 | { "rule": "*-indent", "severity": "off" },
23 | { "rule": "*-spacing", "severity": "off" },
24 | { "rule": "*-spaces", "severity": "off" },
25 | { "rule": "*-order", "severity": "off" },
26 | { "rule": "*-dangle", "severity": "off" },
27 | { "rule": "*-newline", "severity": "off" },
28 | { "rule": "*quotes", "severity": "off" },
29 | { "rule": "*semi", "severity": "off" }
30 | ],
31 |
32 | // Enable eslint for all supported languages
33 | "eslint.validate": [
34 | "javascript",
35 | "javascriptreact",
36 | "typescript",
37 | "typescriptreact",
38 | "html",
39 | "markdown",
40 | "json",
41 | "jsonc",
42 | "yaml",
43 | "toml",
44 | "css",
45 | "less",
46 | "scss",
47 | "sass"
48 | ],
49 |
50 | "css.lint.unknownAtRules": "ignore"
51 | }
52 |
--------------------------------------------------------------------------------
/docs/pages/_theme.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { createTheme, defaultSideNavs } from 'vite-pages-theme-doc'
3 |
4 | import Component404 from './404'
5 |
6 | import type { Theme } from 'vite-plugin-react-pages'
7 |
8 | import './global.css'
9 |
10 | const theme: Theme = (props) => {
11 | const { loadedData, loadState } = props
12 |
13 | const DocTheme = createTheme({
14 | logo: pkg-name
,
15 | topNavs: [
16 | {
17 | label: 'Components',
18 | path: '/components',
19 | activeIfMatch: '/components',
20 | },
21 | {
22 | label: 'Hooks',
23 | path: '/hooks',
24 | activeIfMatch: '/hooks',
25 | },
26 | {
27 | label: 'pkg-name',
28 | href: 'https://github.com/yunsii/starter-vite-react-library',
29 | },
30 | ],
31 | sideNavs: (ctx) => {
32 | return defaultSideNavs(ctx, {
33 | groupConfig: {
34 | components: {
35 | 'demos': {
36 | label: 'Demos (dev only)',
37 | order: -1,
38 | },
39 | 'general': {
40 | label: 'General',
41 | order: 1,
42 | },
43 | 'data-display': {
44 | label: 'Data Display',
45 | order: 2,
46 | },
47 | },
48 | },
49 | })
50 | },
51 | Component404,
52 | })
53 |
54 | return
55 | }
56 |
57 | export default theme
58 |
--------------------------------------------------------------------------------
/vite.docs.config.ts:
--------------------------------------------------------------------------------
1 | import path from 'node:path'
2 |
3 | import { mergeConfig } from 'vite'
4 | import pages, { DefaultPageStrategy } from 'vite-plugin-react-pages'
5 |
6 | import baseConfig from './vite.base.config'
7 |
8 | import type { UserConfig } from 'vite'
9 |
10 | // https://vitejs.dev/config/
11 | export default mergeConfig(baseConfig, {
12 | plugins: [
13 | pages({
14 | pagesDir: path.join(__dirname, 'docs/pages'),
15 | pageStrategy: new DefaultPageStrategy({
16 | extraFindPages: async (pagesDir, helpers) => {
17 | const srcPath = path.join(__dirname, './src')
18 | // show all component demos
19 | helpers.watchFiles(
20 | srcPath,
21 | '**/demos/**/*.{[tj]sx,md?(x)}',
22 | async (file, api) => {
23 | const { relative, path: absolute } = file
24 | const match = relative.match(/(.*)\/demos\/(.*)\.([tj]sx|mdx?)$/)
25 | if (!match) {
26 | throw new Error(`unexpected file: ${absolute}`)
27 | }
28 | const [, componentName, demoName] = match
29 | const pageId = `/${componentName}`
30 | // set page data
31 | const runtimeDataPaths = api.getRuntimeData(pageId)
32 | // the ?demo query will wrap the module with useful demoInfo
33 | runtimeDataPaths[demoName] = `${absolute}?demo`
34 | },
35 | )
36 |
37 | // find all component README
38 | helpers.watchFiles(srcPath, '**/README.md?(x)', async (file, api) => {
39 | const { relative, path: absolute } = file
40 | const match = relative.match(/(.*)\/README\.mdx?$/)
41 | if (!match) {
42 | throw new Error(`unexpected file: ${absolute}`)
43 | }
44 | const [, componentName] = match
45 | const pageId = `/${componentName}`
46 | // set page data
47 | const runtimeDataPaths = api.getRuntimeData(pageId)
48 | runtimeDataPaths.main = absolute
49 | // set page staticData
50 | const staticData = api.getStaticData(pageId)
51 | staticData.main = await helpers.extractStaticData(file)
52 | })
53 | },
54 | }),
55 | }),
56 | ],
57 | build: {
58 | outDir: 'dist-docs',
59 | },
60 | } as UserConfig)
61 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pkg-name",
3 | "type": "module",
4 | "version": "0.0.0",
5 | "packageManager": "pnpm@9.8.0",
6 | "description": "",
7 | "author": "Yuns ",
8 | "license": "MIT",
9 | "funding": [
10 | "https://opencollective.com/yuns",
11 | "https://afdian.net/@yunslove"
12 | ],
13 | "homepage": "https://github.com/yunsii/pkg-name#readme",
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/yunsii/pkg-name"
17 | },
18 | "bugs": "https://github.com/yunsii/pkg-name/issues",
19 | "keywords": [],
20 | "main": "./dist/index.js",
21 | "module": "./dist/index.js",
22 | "types": "./dist/index.d.ts",
23 | "files": [
24 | "dist"
25 | ],
26 | "scripts": {
27 | "dev": "vite --config vite.docs.config.ts",
28 | "build:docs": "tsc && vite build --config vite.docs.config.ts",
29 | "bd": "pnpm run build:docs",
30 | "ssg": "rimraf dist-docs && vite-pages ssr --configFile vite.docs.config.ts",
31 | "ssg:preview": "npm run ssg && serve dist-docs",
32 | "build": "tsc && vite build --config vite.lib.config.ts",
33 | "preview": "vite preview --config vite.docs.config.ts",
34 | "prepare": "husky install",
35 | "lint": "eslint --flag unstable_ts_config .",
36 | "lint:fix": "eslint --flag unstable_ts_config .",
37 | "test": "vitest --config vite.lib.config.ts",
38 | "test:ui": "vitest --config vite.lib.config.ts --ui",
39 | "coverage": "vitest run --config vite.lib.config.ts --coverage"
40 | },
41 | "peerDependencies": {
42 | "react": ">=16.9.0",
43 | "react-dom": ">=16.9.0"
44 | },
45 | "devDependencies": {
46 | "@antfu/eslint-config": "^2.27.1",
47 | "@changesets/cli": "^2.27.1",
48 | "@commitlint/cli": "^19.4.0",
49 | "@commitlint/config-conventional": "^19.2.2",
50 | "@commitlint/types": "^19.0.3",
51 | "@eslint-react/eslint-plugin": "^1.12.1",
52 | "@jannajs/lint": "3.0.0-next.18",
53 | "@mdx-js/react": "^3.0.0",
54 | "@types/node": "^20.11.0",
55 | "@types/react": "^18.2.47",
56 | "@types/react-dom": "^18.2.18",
57 | "@types/react-router-dom": "^5.3.3",
58 | "@types/react-test-renderer": "^18.0.7",
59 | "@vitejs/plugin-react": "^4.3.1",
60 | "@vitest/coverage-v8": "^2.0.5",
61 | "@vitest/ui": "^2.0.5",
62 | "autoprefixer": "^10.4.16",
63 | "eslint": "9.9.0",
64 | "eslint-plugin-format": "^0.1.2",
65 | "eslint-plugin-react-hooks": "5.1.0-rc-fb9a90fa48-20240614",
66 | "eslint-plugin-react-refresh": "^0.4.11",
67 | "husky": "^9.1.5",
68 | "lint-staged": "^15.2.9",
69 | "postcss": "^8.4.33",
70 | "react": "^18.2.0",
71 | "react-dom": "^18.2.0",
72 | "react-router-dom": "^6.21.2",
73 | "react-test-renderer": "^18.2.0",
74 | "rimraf": "^5.0.5",
75 | "serve": "^14.2.1",
76 | "tailwindcss": "^3.4.10",
77 | "tslib": "^2.6.3",
78 | "typescript": "^5.3.3",
79 | "unplugin-auto-import": "^0.18.2",
80 | "vite": "^5.4.2",
81 | "vite-pages-theme-doc": "^5.0.0",
82 | "vite-plugin-dts": "^4.0.3",
83 | "vite-plugin-react-pages": "^5.0.0",
84 | "vite-tsconfig-paths": "^5.0.1",
85 | "vitest": "^2.0.5"
86 | },
87 | "lint-staged": {
88 | "*": "eslint --flag unstable_ts_config --fix"
89 | },
90 | "publishConfig": {
91 | "registry": "https://registry.npmjs.org",
92 | "access": "public"
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/commitlint.config.ts:
--------------------------------------------------------------------------------
1 | import type { UserConfig } from '@commitlint/types'
2 |
3 | const config: UserConfig = {
4 | // ref: https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional
5 | // ref: https://www.conventionalcommits.org/en/v1.0.0/#summary
6 | extends: ['@commitlint/config-conventional'],
7 | // [Question] how to extend and override config-conventional settings:
8 | // https://github.com/conventional-changelog/commitlint/issues/2232
9 | rules: {
10 | 'type-enum': [
11 | 2,
12 | 'always',
13 | [
14 | 'feat',
15 | 'fix',
16 | 'docs',
17 | 'style',
18 | 'refactor',
19 | 'perf',
20 | 'test',
21 | 'build',
22 | 'ci',
23 | 'chore',
24 | 'revert',
25 | ],
26 | ],
27 | },
28 | // ref: https://commitlint.js.org/#/reference-prompt
29 | prompt: {
30 | questions: {
31 | type: {
32 | description: 'Select the type of change that you\'re committing',
33 | enum: {
34 | feat: {
35 | description: 'A new feature',
36 | title: 'Features',
37 | emoji: '✨',
38 | },
39 | fix: {
40 | description: 'A bug fix',
41 | title: 'Bug Fixes',
42 | emoji: '🐛',
43 | },
44 | docs: {
45 | description: 'Documentation only changes',
46 | title: 'Documentation',
47 | emoji: '📚',
48 | },
49 | style: {
50 | description:
51 | 'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
52 | title: 'Styles',
53 | emoji: '💎',
54 | },
55 | refactor: {
56 | description:
57 | 'A code change that neither fixes a bug nor adds a feature',
58 | title: 'Code Refactoring',
59 | emoji: '📦',
60 | },
61 | perf: {
62 | description: 'A code change that improves performance',
63 | title: 'Performance Improvements',
64 | emoji: '🚀',
65 | },
66 | test: {
67 | description: 'Adding missing tests or correcting existing tests',
68 | title: 'Tests',
69 | emoji: '🚨',
70 | },
71 | build: {
72 | description:
73 | 'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
74 | title: 'Builds',
75 | emoji: '🛠',
76 | },
77 | ci: {
78 | description:
79 | 'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
80 | title: 'Continuous Integrations',
81 | emoji: '⚙️',
82 | },
83 | chore: {
84 | description: 'Other changes that don\'t modify src or test files',
85 | title: 'Chores',
86 | emoji: '♻️',
87 | },
88 | revert: {
89 | description: 'Reverts a previous commit',
90 | title: 'Reverts',
91 | emoji: '🗑',
92 | },
93 | },
94 | },
95 | scope: {
96 | description:
97 | 'What is the scope of this change (e.g. component or file name)',
98 | },
99 | subject: {
100 | description:
101 | 'Write a short, imperative tense description of the change',
102 | },
103 | body: {
104 | description: 'Provide a longer description of the change',
105 | },
106 | isBreaking: {
107 | description: 'Are there any breaking changes?',
108 | },
109 | breakingBody: {
110 | description:
111 | 'A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself',
112 | },
113 | breaking: {
114 | description: 'Describe the breaking changes',
115 | },
116 | isIssueAffected: {
117 | description: 'Does this change affect any open issues?',
118 | },
119 | issuesBody: {
120 | description:
121 | 'If issues are closed, the commit requires a body. Please enter a longer description of the commit itself',
122 | },
123 | issues: {
124 | description: 'Add issue references (e.g. "fix #123", "re #123".)',
125 | },
126 | },
127 | },
128 | }
129 |
130 | export default config
131 |
--------------------------------------------------------------------------------