├── .changeset ├── README.md └── config.json ├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .npmrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── auto-imports.d.ts ├── commitlint.config.ts ├── docs └── pages │ ├── $.mdx │ ├── 404.tsx │ ├── _theme.tsx │ └── global.css ├── eslint.config.ts ├── index.html ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── src ├── components │ ├── Button │ │ ├── demos │ │ │ └── demo1.tsx │ │ └── index.tsx │ └── README.md ├── hooks │ ├── README.md │ └── useConsole │ │ ├── demos │ │ └── demo1.tsx │ │ └── index.ts ├── index.ts └── vite.env.d.ts ├── tailwind.config.ts ├── test └── components │ ├── __snapshots__ │ └── button.spec.tsx.snap │ └── button.spec.tsx ├── tsconfig.json ├── tsconfig.node.json ├── vercel.json ├── vite.base.config.ts ├── vite.docs.config.ts └── vite.lib.config.ts /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: yuns 2 | custom: ['https://afdian.net/@yunslove'] 3 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | npx --no -- commitlint --edit $1 2 | npx --no -- @jannajs/lint emojify $1 -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | npx --no -- lint-staged -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist = true 2 | enable-pre-post-scripts = true 3 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pkg-name 2 | 3 | [![NPM version](https://img.shields.io/npm/v/pkg-name?color=a1b858&label=)](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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /docs/pages/$.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | --- 4 | 5 | import README from '../../README.md' 6 | 7 | 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /eslint.config.ts: -------------------------------------------------------------------------------- 1 | import janna from '@jannajs/lint/eslint' 2 | 3 | export default janna() 4 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | pkg-name 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/README.md: -------------------------------------------------------------------------------- 1 | # Components 2 | -------------------------------------------------------------------------------- /src/hooks/README.md: -------------------------------------------------------------------------------- 1 | # Hooks 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Button } from '@/components/Button' 2 | export { default as useConsole } from '@/hooks/useConsole' 3 | -------------------------------------------------------------------------------- /src/vite.env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------