├── .nvmrc ├── packages ├── play │ ├── src │ │ ├── vite-env.d.ts │ │ └── main.ts │ ├── .vscode │ │ └── extensions.json │ ├── public │ │ └── images │ │ │ ├── pet.gif │ │ │ ├── dazuo.png │ │ │ ├── heart.jpg │ │ │ ├── xtaffy.png │ │ │ ├── blackcat.png │ │ │ ├── qianxun.jpg │ │ │ ├── xinlang.jpg │ │ │ ├── Starbucks.png │ │ │ └── image1_portrait.jpg │ ├── .prettierrc.json │ ├── vite.config.ts │ ├── .gitignore │ ├── package.json │ └── index.html ├── theme │ ├── index.css │ ├── fonts │ │ ├── PS2P.woff2 │ │ └── Zpix.woff2 │ └── package.json ├── components │ ├── EyeDropper │ │ ├── style.css │ │ ├── index.ts │ │ └── EyeDropper.test.tsx │ ├── PixelIt │ │ ├── style.css │ │ └── index.ts │ ├── Tag │ │ └── index.ts │ ├── Card │ │ ├── index.ts │ │ ├── Card.vue │ │ └── types.ts │ ├── Icon │ │ ├── index.ts │ │ └── Icon.vue │ ├── Text │ │ ├── index.ts │ │ ├── style.css │ │ └── Text.vue │ ├── Alert │ │ └── index.ts │ ├── Badge │ │ └── index.ts │ ├── Image │ │ ├── index.ts │ │ └── style.css │ ├── Input │ │ └── index.ts │ ├── Switch │ │ └── index.ts │ ├── Overlay │ │ ├── index.ts │ │ └── style.css │ ├── Tooltip │ │ └── index.ts │ ├── Progress │ │ └── index.ts │ ├── Popconfirm │ │ ├── index.ts │ │ └── style.css │ ├── .prettierrc.json │ ├── Message │ │ └── index.ts │ ├── AnimationFrame │ │ ├── index.ts │ │ └── style.css │ ├── Collapse │ │ ├── contants.ts │ │ ├── index.ts │ │ ├── types.collapseItem.ts │ │ └── transitionEvents.ts │ ├── Dropdown │ │ ├── contants.ts │ │ ├── index.ts │ │ ├── types.dropdownItem.ts │ │ └── DropdownItem.vue │ ├── Notification │ │ └── index.ts │ ├── Button │ │ ├── contants.ts │ │ ├── index.ts │ │ └── ButtonGroup.vue │ ├── ConfigProvider │ │ ├── index.ts │ │ ├── constants.ts │ │ ├── ConfigProvider.vue │ │ └── types.ts │ ├── worklets │ │ └── tsconfig.worklet.json │ ├── package.json │ ├── MessageBox │ │ └── index.ts │ ├── Loading │ │ └── index.ts │ └── types │ │ └── worklet.d.ts ├── docs │ ├── vitepress │ │ ├── demo │ │ │ ├── Card │ │ │ │ ├── Hover.vue │ │ │ │ ├── Round.vue │ │ │ │ ├── Simple.vue │ │ │ │ ├── Basic.vue │ │ │ │ ├── Stamp.vue │ │ │ │ └── More.vue │ │ │ ├── Text │ │ │ │ ├── Tag.vue │ │ │ │ ├── Color.vue │ │ │ │ ├── Align.vue │ │ │ │ ├── Size.vue │ │ │ │ └── Basic.vue │ │ │ ├── Badge │ │ │ │ ├── Offset.vue │ │ │ │ ├── Dot.vue │ │ │ │ ├── Max.vue │ │ │ │ ├── Content.vue │ │ │ │ ├── Basic.vue │ │ │ │ └── CustomColor.vue │ │ │ ├── Pixelit │ │ │ │ ├── Basic.vue │ │ │ │ ├── Grayscale.vue │ │ │ │ ├── Size.vue │ │ │ │ └── Palette.vue │ │ │ ├── Button │ │ │ │ ├── Tag.vue │ │ │ │ ├── Throttle.vue │ │ │ │ ├── Icon.vue │ │ │ │ ├── Loading.vue │ │ │ │ ├── Disabled.vue │ │ │ │ ├── Size.vue │ │ │ │ └── Group.vue │ │ │ ├── Popconfirm │ │ │ │ ├── Basic.vue │ │ │ │ ├── Callback.vue │ │ │ │ └── Custom.vue │ │ │ ├── Input │ │ │ │ ├── Basic.vue │ │ │ │ ├── Clearable.vue │ │ │ │ ├── Disabled.vue │ │ │ │ ├── Password.vue │ │ │ │ ├── Textarea.vue │ │ │ │ └── Icon.vue │ │ │ ├── Alert │ │ │ │ ├── Description.vue │ │ │ │ ├── Closable.vue │ │ │ │ ├── Basic.vue │ │ │ │ ├── Icon.vue │ │ │ │ ├── Effect.vue │ │ │ │ ├── Center.vue │ │ │ │ ├── IconDescription.vue │ │ │ │ └── Iron.vue │ │ │ ├── Image │ │ │ │ ├── Basic.vue │ │ │ │ ├── Grid.vue │ │ │ │ └── Custom.vue │ │ │ ├── AnimationFrame │ │ │ │ ├── Loop.vue │ │ │ │ ├── Basic.vue │ │ │ │ └── Stages.vue │ │ │ ├── Switch │ │ │ │ ├── Disabled.vue │ │ │ │ ├── CustomActionIcon.vue │ │ │ │ ├── Loading.vue │ │ │ │ ├── CustomIcon.vue │ │ │ │ ├── Size.vue │ │ │ │ ├── Basic.vue │ │ │ │ └── ExtendedValue.vue │ │ │ ├── Tooltip │ │ │ │ ├── MoreContent.vue │ │ │ │ ├── Trigger.vue │ │ │ │ ├── Advanced.vue │ │ │ │ ├── Virtual.vue │ │ │ │ ├── Transition.vue │ │ │ │ ├── Manual.vue │ │ │ │ └── Theme.vue │ │ │ ├── Icon │ │ │ │ ├── Animation.vue │ │ │ │ ├── Flip.vue │ │ │ │ └── Basic.vue │ │ │ ├── Message │ │ │ │ ├── Center.vue │ │ │ │ ├── Icon.vue │ │ │ │ ├── Global.vue │ │ │ │ └── Basic.vue │ │ │ ├── Notification │ │ │ │ ├── Offset.vue │ │ │ │ ├── Closable.vue │ │ │ │ ├── Global.vue │ │ │ │ ├── Basic.vue │ │ │ │ └── Position.vue │ │ │ ├── EyeDropper │ │ │ │ └── Basic.vue │ │ │ ├── MessageBox │ │ │ │ ├── Icon.vue │ │ │ │ ├── Prompt.vue │ │ │ │ ├── Alert.vue │ │ │ │ ├── Confirm.vue │ │ │ │ ├── VNode.vue │ │ │ │ ├── Center.vue │ │ │ │ └── Style.vue │ │ │ ├── Tag │ │ │ │ ├── Basic.vue │ │ │ │ ├── Closable.vue │ │ │ │ ├── CustomColor.vue │ │ │ │ ├── Size.vue │ │ │ │ └── Effect.vue │ │ │ ├── Progress │ │ │ │ ├── Line.vue │ │ │ │ ├── Content.vue │ │ │ │ ├── Checker.vue │ │ │ │ ├── Inside.vue │ │ │ │ ├── Color.vue │ │ │ │ ├── Indeterminate.vue │ │ │ │ └── Striped.vue │ │ │ ├── Dropdown │ │ │ │ ├── Basic.vue │ │ │ │ ├── HideOnClick.vue │ │ │ │ ├── Manual.vue │ │ │ │ ├── Size.vue │ │ │ │ └── Event.vue │ │ │ ├── Loading │ │ │ │ └── Fullscreen.vue │ │ │ ├── ConfigProvider │ │ │ │ └── I18n.vue │ │ │ ├── Overlay │ │ │ │ ├── Basic.vue │ │ │ │ ├── Grid.vue │ │ │ │ ├── Preset1.vue │ │ │ │ └── Color.vue │ │ │ └── Collapse │ │ │ │ ├── Icon.vue │ │ │ │ ├── Basic.vue │ │ │ │ ├── Accordion.vue │ │ │ │ ├── Disabled.vue │ │ │ │ └── Title.vue │ │ ├── public │ │ │ ├── images │ │ │ │ ├── e.png │ │ │ │ ├── cat.gif │ │ │ │ ├── pet.gif │ │ │ │ ├── monaka.jpg │ │ │ │ ├── taffy.gif │ │ │ │ ├── xtaffy.png │ │ │ │ ├── favicon.ico │ │ │ │ ├── homelogo.png │ │ │ │ ├── twoking.gif │ │ │ │ ├── xinlang.jpg │ │ │ │ ├── Starbucks.png │ │ │ │ └── image1_portrait.jpg │ │ │ └── fonts │ │ │ │ ├── PS2P.woff2 │ │ │ │ └── Zpix.woff2 │ │ ├── .vitepress │ │ │ ├── configs │ │ │ │ ├── index.ts │ │ │ │ ├── head.ts │ │ │ │ ├── nav.ts │ │ │ │ ├── vite.ts │ │ │ │ └── plugins.ts │ │ │ ├── vitepress │ │ │ │ ├── components │ │ │ │ │ ├── fantastic │ │ │ │ │ │ └── pet.vue │ │ │ │ │ ├── bsz.vue │ │ │ │ │ └── globals │ │ │ │ │ │ ├── vp-api-enum.vue │ │ │ │ │ │ └── vp-api-typing.vue │ │ │ │ └── index.ts │ │ │ ├── theme │ │ │ │ └── style │ │ │ │ │ └── hidden.css │ │ │ ├── plugins │ │ │ │ └── tooltip.ts │ │ │ └── config.ts │ │ ├── .prettierrc.json │ │ ├── package.json │ │ ├── components │ │ │ ├── configProvider.md │ │ │ ├── eyeDropper.md │ │ │ ├── text.md │ │ │ ├── image.md │ │ │ ├── collapse.md │ │ │ ├── tag.md │ │ │ ├── animationFrame.md │ │ │ ├── popconfirm.md │ │ │ ├── overlay.md │ │ │ └── pixelit.md │ │ └── .eslintrc.cjs │ └── storybook │ │ ├── assets │ │ └── images │ │ │ ├── e.png │ │ │ ├── pet.gif │ │ │ ├── monaka.jpg │ │ │ ├── taffy.gif │ │ │ ├── xtaffy.png │ │ │ ├── twoking.gif │ │ │ ├── xinlang.jpg │ │ │ └── Starbucks.png │ │ ├── vite.config.ts │ │ ├── .prettierrc.json │ │ ├── .storybook │ │ ├── vitest.setup.ts │ │ ├── preview.tsx │ │ └── main.ts │ │ └── package.json ├── core │ ├── .prettierrc.json │ ├── makeInstaller.ts │ ├── index.ts │ ├── components.ts │ └── printLogo.ts ├── hooks │ ├── .prettierrc.json │ ├── useId.ts │ ├── useClickOutside.ts │ ├── vitest.config.ts │ ├── package.json │ ├── useEventListener.ts │ ├── useOffset.ts │ ├── useZIndex.ts │ ├── index.ts │ ├── __test__ │ │ ├── useClickOutside.test.tsx │ │ ├── useId.test.tsx │ │ └── useLocale.test.tsx │ ├── vite.config.ts │ ├── useLocale.ts │ └── useDisabledStyle.ts ├── utils │ ├── .prettierrc.json │ ├── package.json │ ├── vnode.ts │ ├── rAF.ts │ ├── index.ts │ ├── style.ts │ ├── install.ts │ ├── error.ts │ └── __tests__ │ │ ├── rAF.test.tsx │ │ ├── error.test.tsx │ │ ├── style.test.tsx │ │ └── vnode.test.tsx └── locale │ ├── package.json │ └── index.ts ├── env.d.ts ├── pnpm-workspace.yaml ├── libs ├── vite-plugins │ ├── index.ts │ ├── .dist │ │ ├── index.d.ts │ │ ├── hooksPlugin.d.ts │ │ ├── index.mjs │ │ └── index.cjs │ ├── package.json │ ├── hooksPlugin.ts │ └── vite.config.ts ├── vitepress-preview-component │ ├── .dist │ │ ├── vite.config.d.ts │ │ ├── hooks │ │ │ ├── use-codefold.d.ts │ │ │ ├── use-codecopy.d.ts │ │ │ └── use-namespaces.d.ts │ │ ├── messages │ │ │ ├── index.d.ts │ │ │ └── message-notice.vue.d.ts │ │ ├── icons │ │ │ ├── code-copy.vue.d.ts │ │ │ ├── code-open.vue.d.ts │ │ │ ├── code-close.vue.d.ts │ │ │ └── copy-success.vue.d.ts │ │ └── index.d.ts │ ├── types.d.ts │ ├── hooks │ │ ├── use-codefold.ts │ │ ├── use-codecopy.ts │ │ └── use-namespaces.ts │ ├── index.ts │ ├── vite.config.ts │ ├── tsconfig.json │ ├── icons │ │ ├── copy-success.vue │ │ ├── code-close.vue │ │ └── code-open.vue │ ├── messages │ │ ├── message-notice.scss │ │ ├── index.ts │ │ └── message-notice.vue │ ├── package.json │ └── styles │ │ └── various.scss └── vitepress-api-table │ ├── .dist │ └── index.d.ts │ ├── .prettierrc.json │ ├── rollup.config.ts │ └── package.json ├── .vscode ├── extensions.json └── settings.json ├── .deepsource.toml ├── .prettierrc.json ├── tsconfig.node.json ├── vitest.config.ts ├── .gitignore ├── tsconfig.json └── tsconfig.build.json /.nvmrc: -------------------------------------------------------------------------------- 1 | v20.16.0 -------------------------------------------------------------------------------- /packages/play/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/theme/index.css: -------------------------------------------------------------------------------- 1 | @import './reset.css'; 2 | @import './houdini.css'; -------------------------------------------------------------------------------- /packages/play/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | declare const PROD: boolean 2 | declare const DEV: boolean 3 | declare const TEST: boolean -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/*" 3 | - "packages/docs/*" 4 | - "libs/*" 5 | -------------------------------------------------------------------------------- /libs/vite-plugins/index.ts: -------------------------------------------------------------------------------- 1 | import hooksPlugin from './hooksPlugin' 2 | 3 | export { hooksPlugin } 4 | -------------------------------------------------------------------------------- /packages/components/EyeDropper/style.css: -------------------------------------------------------------------------------- 1 | .px-eyedropper { 2 | width: 100%; 3 | height: 100%; 4 | } -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Card/Hover.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /packages/theme/fonts/PS2P.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/theme/fonts/PS2P.woff2 -------------------------------------------------------------------------------- /packages/theme/fonts/Zpix.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/theme/fonts/Zpix.woff2 -------------------------------------------------------------------------------- /libs/vite-plugins/.dist/index.d.ts: -------------------------------------------------------------------------------- 1 | import { default as hooksPlugin } from './hooksPlugin'; 2 | 3 | export { hooksPlugin }; 4 | -------------------------------------------------------------------------------- /packages/play/public/images/pet.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/pet.gif -------------------------------------------------------------------------------- /packages/play/public/images/dazuo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/dazuo.png -------------------------------------------------------------------------------- /packages/play/public/images/heart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/heart.jpg -------------------------------------------------------------------------------- /packages/play/public/images/xtaffy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/xtaffy.png -------------------------------------------------------------------------------- /packages/play/public/images/blackcat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/blackcat.png -------------------------------------------------------------------------------- /packages/play/public/images/qianxun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/qianxun.jpg -------------------------------------------------------------------------------- /packages/play/public/images/xinlang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/xinlang.jpg -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/vite.config.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: import('vite').UserConfig; 2 | export default _default; 3 | -------------------------------------------------------------------------------- /packages/docs/storybook/assets/images/e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/storybook/assets/images/e.png -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/e.png -------------------------------------------------------------------------------- /packages/play/public/images/Starbucks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/Starbucks.png -------------------------------------------------------------------------------- /packages/docs/storybook/assets/images/pet.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/storybook/assets/images/pet.gif -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/cat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/cat.gif -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/pet.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/pet.gif -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "antfu.unocss", 4 | "lokalise.i18n-ally", 5 | "vitest.explorer" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /packages/docs/storybook/assets/images/monaka.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/storybook/assets/images/monaka.jpg -------------------------------------------------------------------------------- /packages/docs/storybook/assets/images/taffy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/storybook/assets/images/taffy.gif -------------------------------------------------------------------------------- /packages/docs/storybook/assets/images/xtaffy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/storybook/assets/images/xtaffy.png -------------------------------------------------------------------------------- /packages/docs/vitepress/public/fonts/PS2P.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/fonts/PS2P.woff2 -------------------------------------------------------------------------------- /packages/docs/vitepress/public/fonts/Zpix.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/fonts/Zpix.woff2 -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/monaka.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/monaka.jpg -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/taffy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/taffy.gif -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/xtaffy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/xtaffy.png -------------------------------------------------------------------------------- /packages/play/public/images/image1_portrait.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/play/public/images/image1_portrait.jpg -------------------------------------------------------------------------------- /packages/docs/storybook/assets/images/twoking.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/storybook/assets/images/twoking.gif -------------------------------------------------------------------------------- /packages/docs/storybook/assets/images/xinlang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/storybook/assets/images/xinlang.jpg -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/favicon.ico -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/homelogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/homelogo.png -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/twoking.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/twoking.gif -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/xinlang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/xinlang.jpg -------------------------------------------------------------------------------- /packages/docs/storybook/assets/images/Starbucks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/storybook/assets/images/Starbucks.png -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/Starbucks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/Starbucks.png -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Card/Round.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Card/Simple.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/docs/vitepress/public/images/image1_portrait.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maomentai817/pixel-ui/HEAD/packages/docs/vitepress/public/images/image1_portrait.jpg -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Text/Tag.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import { ComponentOptions } from 'vue' 3 | 4 | const comp: ComponentOptions 5 | export default comp 6 | } 7 | -------------------------------------------------------------------------------- /packages/components/PixelIt/style.css: -------------------------------------------------------------------------------- 1 | .px-pixel-it { 2 | display: inline-block; 3 | } 4 | .px-pixel-it__origin { 5 | display: none; 6 | } 7 | canvas { 8 | image-rendering: pixelated; 9 | } -------------------------------------------------------------------------------- /packages/components/Tag/index.ts: -------------------------------------------------------------------------------- 1 | import Tag from './Tag.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxTag = withInstall(Tag) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/configs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './nav' 2 | export * from './sidebar' 3 | export * from './plugins' 4 | export * from './vite' 5 | export * from './head' 6 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Badge/Offset.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /libs/vitepress-api-table/.dist/index.d.ts: -------------------------------------------------------------------------------- 1 | import MarkdownIt from 'markdown-it'; 2 | 3 | declare const apiTableMdPlugin: MarkdownIt.PluginSimple; 4 | 5 | export { apiTableMdPlugin as default }; 6 | -------------------------------------------------------------------------------- /packages/components/Card/index.ts: -------------------------------------------------------------------------------- 1 | import Card from './Card.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxCard = withInstall(Card) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/Icon/index.ts: -------------------------------------------------------------------------------- 1 | import Icon from './Icon.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxIcon = withInstall(Icon) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/Text/index.ts: -------------------------------------------------------------------------------- 1 | import Text from './Text.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxText = withInstall(Text) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "javascript" 5 | 6 | [analyzers.meta] 7 | plugins = ["vue"] 8 | environment = [ 9 | "nodejs", 10 | "vitest" 11 | ] -------------------------------------------------------------------------------- /packages/components/Alert/index.ts: -------------------------------------------------------------------------------- 1 | import Alert from './Alert.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxAlert = withInstall(Alert) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/Badge/index.ts: -------------------------------------------------------------------------------- 1 | import Badge from './Badge.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxBadge = withInstall(Badge) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/Image/index.ts: -------------------------------------------------------------------------------- 1 | import Image from './Image.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxImage = withInstall(Image) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/Image/style.css: -------------------------------------------------------------------------------- 1 | .px-image { 2 | display: inline-block; 3 | overflow: hidden; 4 | } 5 | canvas { 6 | image-rendering: pixelated; 7 | max-width: 100%; 8 | height: auto; 9 | } -------------------------------------------------------------------------------- /packages/components/Input/index.ts: -------------------------------------------------------------------------------- 1 | import Input from './Input.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxInput = withInstall(Input) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Pixelit/Basic.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 100, 7 | "trailingComma": "none" 8 | } -------------------------------------------------------------------------------- /packages/components/Switch/index.ts: -------------------------------------------------------------------------------- 1 | import Switch from './Switch.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxSwitch = withInstall(Switch) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/hooks/use-codefold.d.ts: -------------------------------------------------------------------------------- 1 | export declare const useCodeFold: () => { 2 | isCodeFold: import('vue').Ref; 3 | setCodeFold: (value: boolean) => void; 4 | }; 5 | -------------------------------------------------------------------------------- /packages/components/Overlay/index.ts: -------------------------------------------------------------------------------- 1 | import Overlay from './Overlay.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxOverlay = withInstall(Overlay) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/PixelIt/index.ts: -------------------------------------------------------------------------------- 1 | import PixelIt from './PixelIt.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxPixelIt = withInstall(PixelIt) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/Tooltip/index.ts: -------------------------------------------------------------------------------- 1 | import Tooltip from './Tooltip.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxTooltip = withInstall(Tooltip) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/hooks/use-codecopy.d.ts: -------------------------------------------------------------------------------- 1 | export declare const useCodeCopy: () => { 2 | copyContent: import('vue').Ref; 3 | clickCopy: (value: string) => Promise; 4 | }; 5 | -------------------------------------------------------------------------------- /packages/components/Progress/index.ts: -------------------------------------------------------------------------------- 1 | import Progress from './Progress.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxProgress = withInstall(Progress) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/docs/storybook/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()] 7 | }) 8 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Pixelit/Grayscale.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/components/EyeDropper/index.ts: -------------------------------------------------------------------------------- 1 | import EyeDropper from './EyeDropper.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxEyeDropper = withInstall(EyeDropper) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/Popconfirm/index.ts: -------------------------------------------------------------------------------- 1 | import Popconfirm from './Popconfirm.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxPopconfirm = withInstall(Popconfirm) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/core/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 80, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/hooks/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 80, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/play/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 80, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/utils/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 80, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/components/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 80, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/configs/head.ts: -------------------------------------------------------------------------------- 1 | // configs/head.ts 2 | import type { HeadConfig } from 'vitepress' 3 | 4 | export const head: HeadConfig[] = [ 5 | ['link', { rel: 'icon', href: 'images/favicon.ico' }] 6 | ] 7 | -------------------------------------------------------------------------------- /libs/vitepress-api-table/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 80, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/components/Message/index.ts: -------------------------------------------------------------------------------- 1 | import Message from './methods' 2 | import { withInstallFunction } from '@pixel-ui/utils' 3 | 4 | export const PxMessage = withInstallFunction(Message, '$message') 5 | 6 | export * from './types' 7 | -------------------------------------------------------------------------------- /packages/docs/storybook/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 80, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 80, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Button/Tag.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/components/AnimationFrame/index.ts: -------------------------------------------------------------------------------- 1 | import AnimationFrame from './AnimationFrame.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxAnimationFrame = withInstall(AnimationFrame) 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/components/Collapse/contants.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey } from 'vue' 2 | import type { CollapseContext } from './types.collapse' 3 | 4 | export const COLLAPSE_CTX_KEY: InjectionKey = 5 | Symbol('COLLAPSE_CTX_KEY') 6 | -------------------------------------------------------------------------------- /packages/components/Dropdown/contants.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey } from 'vue' 2 | import type { DropdownContext } from './types.dropdown' 3 | 4 | export const DROPDOWN_CTX_KEY: InjectionKey = 5 | Symbol('DROPDOWN_CTX_KEY') 6 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Popconfirm/Basic.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/components/Notification/index.ts: -------------------------------------------------------------------------------- 1 | import Notification from './methods' 2 | import { withInstallFunction } from '@pixel-ui/utils' 3 | 4 | export const PxNotification = withInstallFunction(Notification, '$notify') 5 | 6 | export * from './types' 7 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/messages/index.d.ts: -------------------------------------------------------------------------------- 1 | import { default as MessageNotice } from './message-notice.vue'; 2 | 3 | declare const MessageNoticeService: { 4 | open: () => void; 5 | }; 6 | export { MessageNotice, MessageNoticeService }; 7 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Input/Basic.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "vitest.disableWorkspaceWarning": true, 3 | "i18n-ally.localesPaths": "packages/locale/lang", 4 | "i18n-ally.enabledParsers": ["ts"], 5 | "i18n-ally.enabledFrameworks": ["vue", "vue-sfc"], 6 | "i18n-ally.keystyle": "nested" 7 | } -------------------------------------------------------------------------------- /packages/components/Button/contants.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey } from 'vue' 2 | import type { ButtonGroupContext } from './types.buttonGroup' 3 | 4 | export const BUTTON_GROUP_CTX_KEY: InjectionKey = Symbol( 5 | 'BUTTON_GROUP_CTX_KEY' 6 | ) 7 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Alert/Description.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/components/ConfigProvider/index.ts: -------------------------------------------------------------------------------- 1 | import ConfigProvider from './ConfigProvider.vue' 2 | import { withInstall } from '@pixel-ui/utils' 3 | 4 | export const PxConfigProvider = withInstall(ConfigProvider) 5 | 6 | export * from './types' 7 | export * from './hooks' 8 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Pixelit/Size.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/components/AnimationFrame/style.css: -------------------------------------------------------------------------------- 1 | .px-animation-frame { 2 | cursor: grab; 3 | user-select: none; 4 | touch-action: none; 5 | contain: layout; 6 | z-index: 99; 7 | } 8 | .super-gif { 9 | image-rendering: pixelated; 10 | cursor: var(--px-cursor-pointer-src) 14 0, pointer; 11 | } -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Image/Basic.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /libs/vite-plugins/.dist/hooksPlugin.d.ts: -------------------------------------------------------------------------------- 1 | export default function hooksPlugin({ rmFiles, beforeBuild, afterBuild }: { 2 | rmFiles?: string[]; 3 | beforeBuild?: Function; 4 | afterBuild?: Function; 5 | }): { 6 | name: string; 7 | buildStart(): void; 8 | buildEnd(err?: Error): void; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/AnimationFrame/Loop.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Input/Clearable.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Input/Disabled.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node18/tsconfig.json", 3 | "include": [ 4 | "packages/**/**.config.ts" 5 | ], 6 | "compilerOptions": { 7 | "composite": true, 8 | "module": "ESNext", 9 | "moduleResolution": "Bundler", 10 | "types": [ 11 | "node" 12 | ] 13 | } 14 | } -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Switch/Disabled.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/icons/code-copy.vue.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly>, {}, {}>; 2 | export default _default; 3 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/icons/code-open.vue.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly>, {}, {}>; 2 | export default _default; 3 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/hooks/use-codefold.ts: -------------------------------------------------------------------------------- 1 | import { ref } from 'vue' 2 | 3 | export const useCodeFold = () => { 4 | const isCodeFold = ref(true) 5 | const setCodeFold = (value: boolean) => { 6 | isCodeFold.value = value 7 | } 8 | return { 9 | isCodeFold, 10 | setCodeFold 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/components/Popconfirm/style.css: -------------------------------------------------------------------------------- 1 | .px-popconfirm .px-popconfirm__main { 2 | display: flex; 3 | align-items: center; 4 | } 5 | 6 | .px-popconfirm .px-popconfirm__main .px-icon { 7 | margin-right: 8px; 8 | } 9 | 10 | .px-popconfirm .px-popconfirm__action { 11 | text-align: right; 12 | margin-top: 8px; 13 | } -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/configs/nav.ts: -------------------------------------------------------------------------------- 1 | // configs/nav.ts 2 | import type { DefaultTheme } from 'vitepress' 3 | 4 | export const nav: DefaultTheme.Config['nav'] = [ 5 | { 6 | text: '开始使用', 7 | link: '/get-started' 8 | }, 9 | { 10 | text: '组件', 11 | link: '/components/button' 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Input/Password.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Switch/CustomActionIcon.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Switch/Loading.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/utils", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "vitest --run --coverage" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "packageManager": "pnpm@10.4.1" 13 | } 14 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/icons/code-close.vue.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly>, {}, {}>; 2 | export default _default; 3 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/icons/copy-success.vue.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly>, {}, {}>; 2 | export default _default; 3 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Badge/Dot.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/index.ts: -------------------------------------------------------------------------------- 1 | import AntDesignContainer from './container/ant-design-ui/AntDesign.vue' 2 | import ElementPlusContainer from './container/element-plus/ElementPlus.vue' 3 | import NaiveUIContainer from './container/naive-ui/NaiveUI.vue' 4 | 5 | export { AntDesignContainer, ElementPlusContainer, NaiveUIContainer } 6 | -------------------------------------------------------------------------------- /packages/play/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import PixelUI from '@mmt817/pixel-ui' 4 | import '@mmt817/pixel-ui/dist/index.css' 5 | import 'virtual:uno.css' 6 | 7 | const app = createApp(App) 8 | 9 | // install pixel-ui components 10 | app.use(PixelUI) 11 | 12 | app.mount('#app') 13 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Input/Textarea.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 15 | -------------------------------------------------------------------------------- /packages/theme/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/theme", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "packageManager": "pnpm@10.4.1" 13 | } 14 | -------------------------------------------------------------------------------- /packages/components/ConfigProvider/constants.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigProviderProps } from './types' 2 | import type { InjectionKey, Ref } from 'vue' 3 | 4 | // 注入上下文属性可选 5 | export type ConfigProviderContext = Partial 6 | 7 | export const ConfigProviderContextKey: InjectionKey< 8 | Ref 9 | > = Symbol() 10 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Alert/Closable.vue: -------------------------------------------------------------------------------- 1 | 5 | 10 | -------------------------------------------------------------------------------- /packages/locale/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/locale", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "", 6 | "main": "index.ts", 7 | "module": "index.ts", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC" 14 | } -------------------------------------------------------------------------------- /packages/components/Button/index.ts: -------------------------------------------------------------------------------- 1 | import Button from './Button.vue' 2 | import ButtonGroup from './ButtonGroup.vue' 3 | import { withInstall } from '@pixel-ui/utils' 4 | 5 | export const PxButton = withInstall(Button) 6 | export const PxButtonGroup = withInstall(ButtonGroup) 7 | 8 | export * from './types.button' 9 | export * from './types.buttonGroup' 10 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/configs/vite.ts: -------------------------------------------------------------------------------- 1 | // configs/vite.ts 2 | import { PluginOption } from 'vite' 3 | import { groupIconVitePlugin } from 'vitepress-plugin-group-icons' 4 | import UnoCSS from 'unocss/vite' 5 | 6 | export const viteConfig = { 7 | plugins: [UnoCSS(), groupIconVitePlugin()] 8 | } satisfies { 9 | plugins: PluginOption[] 10 | } 11 | -------------------------------------------------------------------------------- /packages/components/Collapse/index.ts: -------------------------------------------------------------------------------- 1 | import Collapse from './Collapse.vue' 2 | import CollapseItem from './CollapseItem.vue' 3 | import { withInstall } from '@pixel-ui/utils' 4 | 5 | export const PxCollapse = withInstall(Collapse) 6 | export const PxCollapseItem = withInstall(CollapseItem) 7 | export * from './types.collapse' 8 | export * from './types.collapseItem' 9 | -------------------------------------------------------------------------------- /packages/components/Dropdown/index.ts: -------------------------------------------------------------------------------- 1 | import Dropdown from './Dropdown.vue' 2 | import DropdownItem from './DropdownItem.vue' 3 | import { withInstall } from '@pixel-ui/utils' 4 | 5 | export const PxDropdown = withInstall(Dropdown) 6 | export const PxDropdownItem = withInstall(DropdownItem) 7 | export * from './types.dropdown' 8 | export * from './types.dropdownItem' 9 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tooltip/MoreContent.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/hooks/use-codecopy.ts: -------------------------------------------------------------------------------- 1 | import { ref } from 'vue' 2 | 3 | export const useCodeCopy = () => { 4 | const copyContent = ref('') 5 | const clickCopy = async (value: string) => { 6 | await navigator.clipboard.writeText(value) 7 | // TODO: 通知开发者复制成功 8 | } 9 | return { 10 | copyContent, 11 | clickCopy 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/play/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import UnoCSS from 'unocss/vite' 4 | import { presetUno } from 'unocss' 5 | 6 | // https://vite.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | vue(), 10 | UnoCSS({ 11 | presets: [presetUno()] 12 | }) 13 | ] 14 | }) 15 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Badge/Max.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Icon/Animation.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/AnimationFrame/Basic.vue: -------------------------------------------------------------------------------- 1 | 10 | 13 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Message/Center.vue: -------------------------------------------------------------------------------- 1 | 4 | 15 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Message/Icon.vue: -------------------------------------------------------------------------------- 1 | 4 | 15 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Text/Color.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/play/.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 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/index.d.ts: -------------------------------------------------------------------------------- 1 | import { default as AntDesignContainer } from './container/ant-design-ui/AntDesign.vue'; 2 | import { default as ElementPlusContainer } from './container/element-plus/ElementPlus.vue'; 3 | import { default as NaiveUIContainer } from './container/naive-ui/NaiveUI.vue'; 4 | 5 | export { AntDesignContainer, ElementPlusContainer, NaiveUIContainer }; 6 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Alert/Basic.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Button/Throttle.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /packages/utils/vnode.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { isFunction } from 'lodash-es' 3 | 4 | export const RenderVNode = defineComponent({ 5 | props: { 6 | vNode: { 7 | type: [String, Object, Function], 8 | required: true 9 | } 10 | }, 11 | setup(props) { 12 | return () => (isFunction(props.vNode) ? props.vNode() : props.vNode) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /packages/locale/index.ts: -------------------------------------------------------------------------------- 1 | export { default as en } from './lang/en' 2 | export { default as zhCN } from './lang/zh-cn' 3 | export { default as zhTW } from './lang/zh-tw' 4 | export { default as ja } from './lang/ja' 5 | 6 | export type TranslatePair = { 7 | [key: string]: string | string[] | TranslatePair 8 | } 9 | 10 | export type Language = { 11 | name: string 12 | el: TranslatePair 13 | } 14 | -------------------------------------------------------------------------------- /packages/utils/rAF.ts: -------------------------------------------------------------------------------- 1 | import { nextTick } from 'vue' 2 | 3 | export const rAF = async () => { 4 | return new Promise((res) => { 5 | // 等待一帧, js 清空当前执行栈 6 | requestAnimationFrame(() => { 7 | // 等待下一帧, 确保渲染完成 8 | requestAnimationFrame(async () => { 9 | res(null) 10 | // 确保 Vue 的 DOM 响应式更新完成 11 | await nextTick() 12 | }) 13 | }) 14 | }) 15 | } 16 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Card/Basic.vue: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Notification/Offset.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 16 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tooltip/Trigger.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /packages/play/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/play", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vue-tsc -b && vite build", 9 | "preview": "vite preview", 10 | "prettier": "prettier --write ." 11 | }, 12 | "devDependencies": { 13 | "@vitejs/plugin-vue": "^5.2.1", 14 | "@vue/tsconfig": "^0.7.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/play/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + Vue + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/components/worklets/tsconfig.worklet.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "esnext", 5 | "outDir": "./dist", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "isolatedModules": true, 9 | "esModuleInterop": true, 10 | "noEmitOnError": true, 11 | "allowJs": false, 12 | }, 13 | "include": [ 14 | "./*.worklet.ts", 15 | "../types/*.d.ts" 16 | ] 17 | } -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Alert/Icon.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/hooks/useId.ts: -------------------------------------------------------------------------------- 1 | import { type Ref, computed } from 'vue' 2 | 3 | const defaultIdInjection = { 4 | prefix: Math.floor(Math.random() * 10000), 5 | current: 0 6 | } 7 | 8 | export const useId = (namespace = 'px'): Ref => { 9 | const idRef = computed( 10 | () => 11 | `${namespace}-${defaultIdInjection.prefix}-${defaultIdInjection.current++}}` 12 | ) 13 | return idRef 14 | } 15 | 16 | export default useId 17 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/EyeDropper/Basic.vue: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Notification/Closable.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 16 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Alert/Effect.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/utils/index.ts: -------------------------------------------------------------------------------- 1 | export const typeIconMap = new Map([ 2 | ['info', 'info-circle-solid'], 3 | ['success', 'check-circle-solid'], 4 | ['warning', 'exclamation-triangle-solid'], 5 | ['danger', 'times-circle-solid'], 6 | ['error', 'times-circle-solid'] 7 | ]) 8 | 9 | export * from './install' 10 | export * from './useColorGenerator' 11 | export * from './error' 12 | export * from './style' 13 | export * from './vnode' 14 | export * from './rAF' 15 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Button/Icon.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Alert/Center.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Switch/CustomIcon.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/vitepress/components/fantastic/pet.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 17 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/MessageBox/Icon.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Pixelit/Palette.vue: -------------------------------------------------------------------------------- 1 | 8 | 21 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tooltip/Advanced.vue: -------------------------------------------------------------------------------- 1 | 6 | 17 | -------------------------------------------------------------------------------- /packages/components/ConfigProvider/ConfigProvider.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /packages/components/Text/style.css: -------------------------------------------------------------------------------- 1 | .px-text--base { 2 | color: var(--px-color-base); 3 | } 4 | .px-text--primary { 5 | color: var(--px-color-primary); 6 | } 7 | .px-text--success { 8 | color: var(--px-color-success); 9 | } 10 | .px-text--warning { 11 | color: var(--px-color-warning); 12 | } 13 | .px-text--danger { 14 | color: var(--px-color-danger); 15 | } 16 | .px-text--sakura { 17 | color: var(--px-text-color-sakura); 18 | } 19 | .is-compact { 20 | line-height: 1; 21 | } 22 | -------------------------------------------------------------------------------- /libs/vite-plugins/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/vite-plugins", 3 | "version": "1.0.0", 4 | "private": true, 5 | "type": "module", 6 | "main": "./.dist/index.cjs", 7 | "module": "./.dist/index.mjs", 8 | "types": "./.dist/index.d.ts", 9 | "exports": { 10 | ".": { 11 | "import": "./.dist/index.mjs", 12 | "require": "./.dist/index.cjs", 13 | "types": "./.dist/index.d.ts" 14 | } 15 | }, 16 | "scripts": { 17 | "build": "vite build" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Card/Stamp.vue: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { defineConfig } from 'vite' 3 | import vue from '@vitejs/plugin-vue' 4 | import vueJsx from '@vitejs/plugin-vue-jsx' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue(), vueJsx()], 9 | define: { 10 | PROD: JSON.stringify(false), 11 | DEV: JSON.stringify(false), 12 | TEST: JSON.stringify(true) 13 | }, 14 | test: { 15 | globals: true, 16 | environment: 'jsdom' 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /packages/hooks/useClickOutside.ts: -------------------------------------------------------------------------------- 1 | import { type Ref } from 'vue' 2 | import useEventListener from './useEventListener' 3 | 4 | export default function useClickOutside( 5 | elementRef: Ref, 6 | callback: (_e: MouseEvent) => void 7 | ) { 8 | useEventListener(document, 'click', (e: Event) => { 9 | if (elementRef.value && e.target) { 10 | if (!elementRef.value.contains(e.target as HTMLElement)) { 11 | callback(e as MouseEvent) 12 | } 13 | } 14 | }) 15 | } 16 | -------------------------------------------------------------------------------- /packages/docs/storybook/.storybook/vitest.setup.ts: -------------------------------------------------------------------------------- 1 | import { beforeAll } from 'vitest' 2 | import { setProjectAnnotations } from '@storybook/vue3' 3 | import * as projectAnnotations from './preview' 4 | 5 | // This is an important step to apply the right configuration when testing your stories. 6 | // More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations 7 | const project = setProjectAnnotations([projectAnnotations]) 8 | 9 | beforeAll(project.beforeAll) 10 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Text/Align.vue: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/AnimationFrame/Stages.vue: -------------------------------------------------------------------------------- 1 | 10 | 18 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Image/Grid.vue: -------------------------------------------------------------------------------- 1 | 14 | 19 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tooltip/Virtual.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | -------------------------------------------------------------------------------- /packages/core/makeInstaller.ts: -------------------------------------------------------------------------------- 1 | import { each } from 'lodash-es' 2 | import type { App, Plugin } from 'vue' 3 | import { 4 | provideGlobalConfig, 5 | type ConfigProviderProps 6 | } from '@pixel-ui/components' 7 | 8 | export function makeInstaller(componets: Plugin[]) { 9 | const installer = (app: App, opts?: ConfigProviderProps) => { 10 | each(componets, (c) => app.use(c)) 11 | if (opts) provideGlobalConfig(opts, app, true) 12 | } 13 | 14 | return installer as Plugin 15 | } 16 | 17 | export default makeInstaller 18 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Text/Size.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /packages/hooks/vitest.config.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { defineConfig } from 'vite' 3 | import vue from '@vitejs/plugin-vue' 4 | import vueJsx from '@vitejs/plugin-vue-jsx' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue(), vueJsx()], 9 | test: { 10 | globals: true, 11 | environment: 'jsdom', 12 | exclude: [ 13 | '**/node_modules/**', 14 | '**/dist/**', 15 | '**/true/coverage/**', 16 | '**/coverage/**' 17 | ] 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tooltip/Transition.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /libs/vite-plugins/.dist/index.mjs: -------------------------------------------------------------------------------- 1 | import { isFunction, each } from "lodash-es"; 2 | import shell from "shelljs"; 3 | function hooksPlugin({ 4 | rmFiles = [], 5 | beforeBuild, 6 | afterBuild 7 | }) { 8 | return { 9 | name: "hooks-plugin", 10 | buildStart() { 11 | each(rmFiles, (fileName) => shell.rm("-rf", fileName)); 12 | isFunction(beforeBuild) && beforeBuild(); 13 | }, 14 | buildEnd(err) { 15 | !err && isFunction(afterBuild) && afterBuild(); 16 | } 17 | }; 18 | } 19 | export { 20 | hooksPlugin 21 | }; 22 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/vitepress/components/bsz.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Button/Loading.vue: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /packages/docs/storybook/.storybook/preview.tsx: -------------------------------------------------------------------------------- 1 | import type { Preview } from '@storybook/vue3' 2 | 3 | import "@hackernoon/pixel-icon-library/fonts/iconfont.css" 4 | import '@mmt817/pixel-ui/dist/theme/index.css' 5 | import { registerPaintWorklets } from '@mmt817/pixel-ui' 6 | 7 | const preview: Preview = { 8 | parameters: { 9 | controls: { 10 | matchers: { 11 | color: /(background|color)$/i, 12 | date: /Date$/i 13 | } 14 | } 15 | } 16 | } 17 | 18 | // 预加载注册 paintWorklets 19 | registerPaintWorklets() 20 | 21 | export default preview 22 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Switch/Size.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 26 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Switch/Basic.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 22 | -------------------------------------------------------------------------------- /packages/components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/components", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "cross-env NODE_ENV=test pnpm --filter @pixel-ui/hooks build && vitest --run --coverage", 8 | "test:watch": "cross-env NODE_ENV=test pnpm --filter @pixel-ui/hooks build && vitest --coverage", 9 | "prettier": "prettier --write .", 10 | "worklet": "tsc -p ./worklets/tsconfig.worklet.json" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "packageManager": "pnpm@10.4.1" 16 | } 17 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Message/Global.vue: -------------------------------------------------------------------------------- 1 | 10 | 23 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/hooks/use-namespaces.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 钩子函数使用 3 | * const ns = useNameSpace(); 4 | * ns.b() => block 5 | * ns.e(element) => block__element 6 | * ns.m(modifier) => block--modifier 7 | * ns.bem(element,modifier) => block__element--modifier 8 | */ 9 | interface UseNameSpaceReturn { 10 | b: () => string; 11 | e: (element: string) => string; 12 | m: (modifier: string) => string; 13 | bem: (_block?: string, element?: string, modifier?: string) => string; 14 | } 15 | export declare const useNameSpace: (block?: string) => UseNameSpaceReturn; 16 | export {}; 17 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/vitepress/components/globals/vp-api-enum.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tag/Basic.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 21 | -------------------------------------------------------------------------------- /packages/utils/style.ts: -------------------------------------------------------------------------------- 1 | import { isNumber, isString } from 'lodash-es' 2 | import { debugWarn } from './error' 3 | 4 | const SCOPE = 'utils/style' as const 5 | 6 | // 检测是否为字符串数字 7 | const isStringNumber = (val: string): boolean => { 8 | if (!isString(val)) return false 9 | return !Number.isNaN(Number(val)) 10 | } 11 | 12 | export const addUnit = (val?: string | number, defaultUnit = 'px') => { 13 | if (!val) return '' 14 | if (isNumber(val) || isStringNumber(val)) return `${val}${defaultUnit}` 15 | if (isString(val)) return val 16 | debugWarn(SCOPE, `binding value must be a string or number`) 17 | } 18 | -------------------------------------------------------------------------------- /packages/components/MessageBox/index.ts: -------------------------------------------------------------------------------- 1 | import MessageBox from './methods' 2 | import { set } from 'lodash-es' 3 | import type { App } from 'vue' 4 | 5 | export const PxMessageBox = MessageBox 6 | 7 | set(PxMessageBox, 'install', (app: App) => { 8 | app.config.globalProperties.$msgbox = MessageBox 9 | app.config.globalProperties.$messagebox = MessageBox 10 | app.config.globalProperties.$alert = MessageBox.alert 11 | app.config.globalProperties.$confirm = MessageBox.confirm 12 | app.config.globalProperties.$prompt = MessageBox.prompt 13 | }) 14 | 15 | export default PxMessageBox 16 | export * from './types' 17 | -------------------------------------------------------------------------------- /libs/vite-plugins/hooksPlugin.ts: -------------------------------------------------------------------------------- 1 | import { each, isFunction } from 'lodash-es' 2 | import shell from 'shelljs' 3 | 4 | export default function hooksPlugin({ 5 | rmFiles = [], 6 | beforeBuild, 7 | afterBuild 8 | }: { 9 | rmFiles?: string[] 10 | beforeBuild?: Function 11 | afterBuild?: Function 12 | }) { 13 | return { 14 | name: 'hooks-plugin', 15 | buildStart() { 16 | each(rmFiles, (fileName) => shell.rm('-rf', fileName)) 17 | isFunction(beforeBuild) && beforeBuild() 18 | }, 19 | buildEnd(err?: Error) { 20 | !err && isFunction(afterBuild) && afterBuild() 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/MessageBox/Prompt.vue: -------------------------------------------------------------------------------- 1 | 4 | 21 | -------------------------------------------------------------------------------- /packages/components/Loading/index.ts: -------------------------------------------------------------------------------- 1 | import Loading from './service' 2 | import vLoading from './directive' 3 | import type { App } from 'vue' 4 | 5 | export const PxLoading = { 6 | name: 'PxLoading', 7 | install(app: App) { 8 | // 指令式调用 v-loading 9 | app.directive('loading', vLoading) 10 | // 全局方法 $loading 11 | app.config.globalProperties.$loading = Loading 12 | }, 13 | // 指令式调用 14 | directive: vLoading, 15 | // 函数式调用 16 | service: Loading 17 | } 18 | 19 | export default PxLoading 20 | 21 | export { vLoading, vLoading as PxLoadingDirective, Loading as PxLoadingService } 22 | 23 | export * from './types' 24 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/configs/plugins.ts: -------------------------------------------------------------------------------- 1 | // configs/plugins.ts 2 | import type { MarkdownRenderer } from 'vitepress' 3 | import { 4 | containerPreview, 5 | componentPreview 6 | } from '@vitepress-demo-preview/plugin' 7 | import { groupIconMdPlugin } from 'vitepress-plugin-group-icons' 8 | import tooltip from '../plugins/tooltip' 9 | import apiTable from 'vitepress-api-table' 10 | 11 | export const mdPlugin = (md: MarkdownRenderer) => { 12 | md.use(containerPreview) 13 | md.use(componentPreview) 14 | md.use(apiTable) 15 | md.use(tooltip) 16 | //@ts-ignore 这里报错需要重新装包, 依赖本身问题 17 | md.use(groupIconMdPlugin) 18 | } 19 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Icon/Flip.vue: -------------------------------------------------------------------------------- 1 | 31 | -------------------------------------------------------------------------------- /packages/hooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/hooks", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "module": "./dist/index.js", 6 | "types": "./dist/index.d.ts", 7 | "files": [ 8 | "dist" 9 | ], 10 | "exports": { 11 | ".": { 12 | "import": "./dist/index.js", 13 | "types": "./dist/index.d.ts" 14 | } 15 | }, 16 | "scripts": { 17 | "test": "vitest --run --coverage", 18 | "build": "vite build" 19 | }, 20 | "license": "ISC", 21 | "peerDependencies": { 22 | "lodash-es": "^4.17.21", 23 | "vue": "^3.4.19" 24 | }, 25 | "devDependencies": { 26 | "vue": "^3.4.19" 27 | } 28 | } -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Card/More.vue: -------------------------------------------------------------------------------- 1 | 6 | 23 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Badge/Content.vue: -------------------------------------------------------------------------------- 1 | 18 | 23 | -------------------------------------------------------------------------------- /packages/utils/install.ts: -------------------------------------------------------------------------------- 1 | import type { App, Plugin } from 'vue' 2 | 3 | type SFCWithInstall = T & Plugin 4 | 5 | // component install function 6 | export const withInstall = (component: T) => { 7 | ;(component as SFCWithInstall).install = (app: App) => { 8 | const name = (component as any).name 9 | app.component(name, component as Plugin) 10 | } 11 | 12 | return component as SFCWithInstall 13 | } 14 | 15 | export const withInstallFunction = (fn: T, name: string) => { 16 | ;(fn as SFCWithInstall).install = (app: App) => { 17 | app.config.globalProperties[name] = fn 18 | } 19 | return fn as SFCWithInstall 20 | } 21 | -------------------------------------------------------------------------------- /libs/vite-plugins/.dist/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); 3 | const lodashEs = require("lodash-es"); 4 | const shell = require("shelljs"); 5 | function hooksPlugin({ 6 | rmFiles = [], 7 | beforeBuild, 8 | afterBuild 9 | }) { 10 | return { 11 | name: "hooks-plugin", 12 | buildStart() { 13 | lodashEs.each(rmFiles, (fileName) => shell.rm("-rf", fileName)); 14 | lodashEs.isFunction(beforeBuild) && beforeBuild(); 15 | }, 16 | buildEnd(err) { 17 | !err && lodashEs.isFunction(afterBuild) && afterBuild(); 18 | } 19 | }; 20 | } 21 | exports.hooksPlugin = hooksPlugin; 22 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Switch/ExtendedValue.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 23 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tooltip/Manual.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Message/Basic.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 23 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Progress/Line.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 16 | -------------------------------------------------------------------------------- /packages/components/ConfigProvider/types.ts: -------------------------------------------------------------------------------- 1 | import type { Language, TranslatePair } from '@pixel-ui/locale' 2 | 3 | export interface ConfigProviderProps { 4 | /** 5 | * @property locale 6 | * @type Object - {name: string, el: TranslatePair} 7 | * @description 翻译文本对象 8 | * @default en 9 | */ 10 | locale?: Language 11 | /** 12 | * @property extendsI18nMsg 13 | * @type {TranslatePair} 14 | * @description 扩展翻译文本对象 15 | * @default {} 16 | */ 17 | extendsI18nMsg?: TranslatePair 18 | } 19 | 20 | export interface ConfigProviderSlots { 21 | /** 22 | * @property default 23 | * @description 自定义默认内容,提供全局配置 24 | */ 25 | default: () => string 26 | } 27 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Badge/Basic.vue: -------------------------------------------------------------------------------- 1 | 18 | 23 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/MessageBox/Alert.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 27 | -------------------------------------------------------------------------------- /packages/hooks/useEventListener.ts: -------------------------------------------------------------------------------- 1 | import { 2 | onMounted, 3 | onBeforeUnmount, 4 | watch, 5 | isRef, 6 | unref, 7 | type MaybeRef 8 | } from 'vue' 9 | 10 | export default function useEventListener( 11 | target: MaybeRef, 12 | event: string, 13 | handler: (_e: Event) => any 14 | ) { 15 | if (isRef(target)) { 16 | watch(target, (val, oldVal) => { 17 | oldVal?.removeEventListener(event, handler) 18 | val?.addEventListener(event, handler) 19 | }) 20 | } else { 21 | onMounted(() => target?.addEventListener(event, handler)) 22 | } 23 | 24 | onBeforeUnmount(() => unref(target)?.removeEventListener(event, handler)) 25 | } 26 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import { resolve } from "path"; 3 | import vue from "@vitejs/plugin-vue"; 4 | import dts from "vite-plugin-dts"; 5 | 6 | export default defineConfig({ 7 | build: { 8 | outDir: ".dist", 9 | lib: { 10 | entry: resolve(__dirname, "./index.ts"), 11 | name: "previewComponent", 12 | fileName: "preview-component", 13 | formats: ["es"], 14 | }, 15 | rollupOptions: { 16 | external: ["vue"], 17 | output: { 18 | globals: { 19 | vue: "Vue", 20 | }, 21 | }, 22 | }, 23 | }, 24 | plugins: [vue(), dts({ insertTypesEntry: true })], 25 | }); 26 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Dropdown/Basic.vue: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "es2018", 5 | "module": "esnext", 6 | "lib": ["esnext", "DOM"], 7 | "moduleResolution": "node", 8 | "esModuleInterop": true, 9 | "strict": true, 10 | "strictNullChecks": true, 11 | "resolveJsonModule": true, 12 | "skipLibCheck": true, 13 | "skipDefaultLibCheck": true, 14 | "paths": { 15 | "tslib": ["node_modules/tslib/tslib.d.ts"] 16 | } 17 | }, 18 | "vueCompilerOptions": { 19 | // "experimentalDisableTemplateSupport": true 20 | }, 21 | "include": ["**/*.vue", "**/*.ts", "**/*.d.ts"], 22 | "exclude": ["**/node_modules", "**/dist"] 23 | } 24 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Popconfirm/Callback.vue: -------------------------------------------------------------------------------- 1 | 9 | 26 | -------------------------------------------------------------------------------- /packages/core/index.ts: -------------------------------------------------------------------------------- 1 | // import { makeInstaller } from '@pixel-ui/utils' 2 | 3 | import '@hackernoon/pixel-icon-library/fonts/iconfont.css' 4 | import '@pixel-ui/theme/index.css' 5 | 6 | import components from './components' 7 | import printLogo from './printLogo' 8 | import makeInstaller from './makeInstaller' 9 | 10 | // 统一注册 paintWorklet 11 | import { registerPaintWorklets } from '@pixel-ui/components' 12 | 13 | printLogo() 14 | 15 | // 注册组件之前执行 Paint Worklet 注册 16 | registerPaintWorklets() 17 | const installer = makeInstaller(components) 18 | 19 | export * from '@pixel-ui/components' 20 | // export * from '@pixel-ui/locale' 21 | export { en, zhCN, zhTW, ja } from '@pixel-ui/locale' 22 | export default installer 23 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/vitepress/index.ts: -------------------------------------------------------------------------------- 1 | import ApiTyping from './components/globals/vp-api-typing.vue' 2 | import ApiEnum from './components/globals/vp-api-enum.vue' 3 | import IconList from './components/globals/icons.vue' 4 | import ImageCompare from './components/globals/image-compare.vue' 5 | import PixelitCompare from './components/globals/pixelit-compare.vue' 6 | import bsz from './components/bsz.vue' 7 | import type { Component } from 'vue' 8 | 9 | export const globals: [string, Component][] = [ 10 | ['ApiTyping', ApiTyping], 11 | ['ApiEnum', ApiEnum], 12 | ['IconList', IconList], 13 | ['ImageCompare', ImageCompare], 14 | ['PixelitCompare', PixelitCompare] 15 | ] 16 | 17 | export default bsz 18 | -------------------------------------------------------------------------------- /packages/hooks/useOffset.ts: -------------------------------------------------------------------------------- 1 | import { computed, type Ref } from 'vue' 2 | 3 | interface UseOffsetOptions { 4 | offset: number 5 | boxHeight: Ref 6 | getLastBottomOffset: () => number 7 | } 8 | 9 | interface UseOffsetResult { 10 | topOffset: Ref 11 | bottomOffset: Ref 12 | } 13 | 14 | export const useOffset = (opts: UseOffsetOptions): UseOffsetResult => { 15 | const lastBottomOffset = computed(() => opts.getLastBottomOffset()) 16 | 17 | const topOffset = computed(() => opts.offset + lastBottomOffset.value) 18 | 19 | const bottomOffset = computed(() => topOffset.value + opts.boxHeight.value) 20 | 21 | return { topOffset, bottomOffset } 22 | } 23 | 24 | export default useOffset 25 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tag/Closable.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 23 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Input/Icon.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 26 | -------------------------------------------------------------------------------- /packages/hooks/useZIndex.ts: -------------------------------------------------------------------------------- 1 | import { ref, computed, type Ref, type ComputedRef } from 'vue' 2 | 3 | /** @internal 用于测试中重置全局 zIndex */ 4 | export const zIndex = ref(0) 5 | 6 | interface UseZIndexResult { 7 | initialValue: Ref 8 | currentZIndex: ComputedRef 9 | nextZIndex: () => number 10 | } 11 | export const useZIndex = (initVal = 2000): UseZIndexResult => { 12 | const _initVal = ref(initVal) 13 | const currentZIndex = computed(() => zIndex.value + _initVal.value) 14 | 15 | const nextZIndex = () => { 16 | zIndex.value += 1 17 | return currentZIndex.value 18 | } 19 | 20 | return { 21 | initialValue: _initVal, 22 | currentZIndex, 23 | nextZIndex 24 | } 25 | } 26 | 27 | export default useZIndex 28 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tag/CustomColor.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 23 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tooltip/Theme.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 26 | -------------------------------------------------------------------------------- /packages/docs/vitepress/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/vitepress", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "vitepress dev ./", 9 | "build": "vitepress build ./", 10 | "preview": "vitepress preview ./" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "packageManager": "pnpm@10.4.1", 16 | "devDependencies": { 17 | "@vitepress-demo-preview/plugin": "^1.2.3", 18 | "busuanzi.pure.js": "^1.0.3", 19 | "nprogress-v2": "^1.1.10", 20 | "vitepress": "^1.6.3", 21 | "vitepress-plugin-group-icons": "^1.5.2", 22 | "vitepress-preview-component": "workspace:*", 23 | "vitepress-api-table": "workspace:*" 24 | } 25 | } -------------------------------------------------------------------------------- /packages/components/Overlay/style.css: -------------------------------------------------------------------------------- 1 | .px-overlay { 2 | position: fixed; 3 | inset: 0; 4 | height: 100%; 5 | background-color: #00000080; 6 | overflow: auto; 7 | z-index: 2000; 8 | } 9 | 10 | .px-overlay.is-transparent { 11 | background-color: transparent; 12 | } 13 | 14 | .is-grid-basic { 15 | background: none; 16 | background-color: transparent !important; 17 | background-image: paint(pixelgridBasic); 18 | } 19 | 20 | .is-matte { 21 | mask-image: radial-gradient(circle at center, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.8), transparent); 22 | mask-size: cover; 23 | mask-repeat: no-repeat; 24 | } 25 | 26 | .is-grid-preset-1 { 27 | background: none; 28 | background-color: transparent !important; 29 | background-image: paint(pixelgridPreset1); 30 | } 31 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Button/Disabled.vue: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /packages/hooks/index.ts: -------------------------------------------------------------------------------- 1 | import useClickOutside from './useClickOutside' 2 | import useEventListener from './useEventListener' 3 | import useId from './useId' 4 | import useDisabledStyle from './useDisabledStyle' 5 | import useLocale from './useLocale' 6 | import useOffset from './useOffset' 7 | import useZIndex from './useZIndex' 8 | import useFocusController from './useFocusController' 9 | import useDraggable from './useDraggable' 10 | import { usePxBadgeCustomStyle, usePxButtonCustomStyle } from './useColor' 11 | 12 | export { 13 | useClickOutside, 14 | useEventListener, 15 | useId, 16 | useDisabledStyle, 17 | useLocale, 18 | usePxButtonCustomStyle, 19 | usePxBadgeCustomStyle, 20 | useOffset, 21 | useZIndex, 22 | useFocusController, 23 | useDraggable 24 | } 25 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Progress/Content.vue: -------------------------------------------------------------------------------- 1 | 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node.js 依赖 2 | node_modules/ 3 | # pnpm-lock.yaml 4 | *.log 5 | 6 | # Vite 相关 7 | .vite/ 8 | dist/ 9 | .cache/ 10 | *.local 11 | 12 | # Storybook 相关 13 | packages/docs/storybook/.storybook/out/ 14 | packages/docs/storybook/.storybook/.cache/ 15 | packages/docs/storybook/storybook-static/ 16 | packages/docs/storybook/problem/ 17 | 18 | # VitePress 相关 19 | packages/docs/vitepress/.vitepress/cache/ 20 | packages/docs/vitepress/.vitepress/dist/ 21 | 22 | # 测试 & 构建 23 | coverage/ 24 | tests/output/ 25 | *.test.js 26 | *.test.ts 27 | jest-cache/ 28 | jest-transform-cache/ 29 | *.spec.ts 30 | 31 | # 编辑器 & 操作系统 32 | .DS_Store 33 | Thumbs.db 34 | .idea/ 35 | # .vscode/ 36 | *.swp 37 | *.swo 38 | *.sublime-workspace 39 | 40 | # 打包 & 发布 41 | *.tgz 42 | *.bak 43 | *.tmp 44 | 45 | *storybook.log 46 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/MessageBox/Confirm.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 32 | -------------------------------------------------------------------------------- /libs/vite-plugins/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | import { resolve } from "path" 3 | import dts from "vite-plugin-dts" 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | dts({ 8 | include: ["./**/*.ts"], 9 | exclude: ["./vite.config.ts"], 10 | }), 11 | ], 12 | build: { 13 | minify: false, 14 | outDir: ".dist", 15 | lib: { 16 | entry: resolve(__dirname, "./index.ts"), 17 | name: "vitePlugins", 18 | }, 19 | rollupOptions: { 20 | external: ["shelljs", "lodash-es"], 21 | output: [ 22 | { 23 | format: "esm", 24 | entryFileNames: "index.mjs", 25 | }, 26 | { 27 | format: "cjs", 28 | entryFileNames: "index.cjs", 29 | }, 30 | ], 31 | }, 32 | }, 33 | }) 34 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Text/Basic.vue: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Notification/Global.vue: -------------------------------------------------------------------------------- 1 | 17 | 34 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Progress/Checker.vue: -------------------------------------------------------------------------------- 1 | 34 | -------------------------------------------------------------------------------- /libs/vitepress-api-table/rollup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'rollup' 2 | import typescript from '@rollup/plugin-typescript' 3 | import dts from 'rollup-plugin-dts' 4 | 5 | export default defineConfig([ 6 | { 7 | input: './index.ts', 8 | output: [ 9 | { 10 | file: '.dist/index.cjs', 11 | format: 'cjs' 12 | }, 13 | { 14 | file: '.dist/index.mjs', 15 | format: 'esm' 16 | } 17 | ], 18 | plugins: [ 19 | typescript({ 20 | compilerOptions: { lib: ['esnext'] }, 21 | allowSyntheticDefaultImports: true 22 | }) 23 | ], 24 | watch: { 25 | exclude: 'node_modules/**' 26 | } 27 | }, 28 | { 29 | input: './index.ts', 30 | output: [{ file: './.dist/index.d.ts', format: 'esm' }], 31 | plugins: [dts()] 32 | } 33 | ]) 34 | -------------------------------------------------------------------------------- /packages/utils/error.ts: -------------------------------------------------------------------------------- 1 | import { isString } from 'lodash-es' 2 | 3 | export class PxUIError extends Error { 4 | constructor(message: string | Error) { 5 | super(isString(message) ? message : message.message) 6 | this.name = 'PxUIError' 7 | } 8 | } 9 | const createPxUIError = (scope: string, msg: string) => { 10 | return new PxUIError(`[${scope}]: ${msg}`) 11 | } 12 | export const throwError = (scope: string, msg: string) => { 13 | throw createPxUIError(scope, msg) 14 | } 15 | 16 | export function debugWarn(_error: Error): void 17 | export function debugWarn(_scope: string, _msg: string): void 18 | export function debugWarn(scope: string | Error, msg?: string) { 19 | if (process.env.NODE_ENV !== 'production') { 20 | const err = isString(scope) ? createPxUIError(scope, msg!) : scope 21 | console.warn(err) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/MessageBox/VNode.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 36 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/MessageBox/Center.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 33 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Notification/Basic.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 30 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/icons/copy-success.vue: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Alert/IconDescription.vue: -------------------------------------------------------------------------------- 1 | 35 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Popconfirm/Custom.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 34 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/theme/style/hidden.css: -------------------------------------------------------------------------------- 1 | /* .vitepress\theme\style\hidden.css */ 2 | :root { 3 | 4 | /* 文档页Logo出文字下横条 */ 5 | @media (min-width: 960px) { 6 | .VPNavBarTitle.has-sidebar .title { 7 | border-bottom-color: transparent; 8 | } 9 | } 10 | 11 | /* 页脚横条隐藏 */ 12 | .VPFooter { 13 | border-top: none; 14 | } 15 | 16 | /* 手机端菜单栏顶部横条隐藏 */ 17 | .VPNavBar.screen-open { 18 | border-bottom: none; 19 | } 20 | 21 | /* 手机端菜单栏菜单分割线隐藏 */ 22 | .VPNavScreenMenuLink { 23 | border-bottom: none; 24 | } 25 | 26 | /* 手机端菜单组隐藏 */ 27 | .VPNavScreenMenuGroup { 28 | border-bottom: none; 29 | } 30 | 31 | /* 手机端大纲栏横条隐藏 */ 32 | .VPLocalNav { 33 | border-bottom: none; 34 | } 35 | 36 | } 37 | 38 | 39 | /* 导航栏下划线隐藏 */ 40 | .divider { 41 | display: none; 42 | } -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Loading/Fullscreen.vue: -------------------------------------------------------------------------------- 1 | 11 | 36 | -------------------------------------------------------------------------------- /packages/utils/__tests__/rAF.test.tsx: -------------------------------------------------------------------------------- 1 | // rAF.test.tsx 2 | import { describe, it, expect, vi } from 'vitest' 3 | import { rAF } from '../rAF' 4 | import { ref } from 'vue' 5 | 6 | describe('rAF utility function', () => { 7 | it('should resolve after two animation frames and nextTick', async () => { 8 | const fn = vi.fn() 9 | await rAF() 10 | fn() 11 | 12 | expect(fn).toHaveBeenCalled() 13 | }) 14 | 15 | it('should wait for DOM update after reactive change', async () => { 16 | const counter = ref(0) 17 | 18 | counter.value = 10 19 | 20 | const afterUpdate = vi.fn(() => { 21 | expect(counter.value).toBe(10) 22 | }) 23 | 24 | await rAF() 25 | afterUpdate() 26 | 27 | expect(afterUpdate).toHaveBeenCalled() 28 | }) 29 | 30 | it('should return a Promise', () => { 31 | const result = rAF() 32 | expect(result).toBeInstanceOf(Promise) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/messages/message-notice.scss: -------------------------------------------------------------------------------- 1 | @import '../styles/various.scss'; 2 | 3 | .#{$defaultPrefix}-message-notice__container { 4 | display: flex; 5 | align-items: center; 6 | border: 1px solid var(--component-preview-border); 7 | padding: 8px 30px; 8 | border-radius: 4px; 9 | font-size: 12px; 10 | color: var(--component-preview-primary-color); 11 | position: fixed; 12 | left: 50%; 13 | transform: translateX(-50%); 14 | z-index: 999; 15 | 16 | svg { 17 | display: inline-block; 18 | fill: currentColor; 19 | color: var(--component-preview-primary-color); 20 | cursor: pointer; 21 | margin-right: 4px; 22 | } 23 | } 24 | 25 | .slide-fade-leave-active, 26 | .slide-fade-enter-active { 27 | transition: all 0.25s ease-in-out; 28 | } 29 | 30 | .slide-fade-enter-from, 31 | .slide-fade-leave-to { 32 | transform: translate(-50%, -75px); 33 | opacity: 0; 34 | } 35 | -------------------------------------------------------------------------------- /packages/components/Text/Text.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | 37 | 40 | -------------------------------------------------------------------------------- /packages/components/Button/ButtonGroup.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 32 | 33 | 36 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Progress/Inside.vue: -------------------------------------------------------------------------------- 1 | 39 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/icons/code-close.vue: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vitepress-preview-component", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "main": "./.dist/preview-component.umd.cjs", 7 | "module": "./.dist/preview-component.js", 8 | "types": "./.dist/index.d.ts", 9 | "exports": { 10 | ".": { 11 | "import": "./.dist/preview-component.js", 12 | "require": "./.dist/preview-component.umd.cjs" 13 | }, 14 | "./style.css": "./.dist/style.css" 15 | }, 16 | "files": [ 17 | ".dist", 18 | "README.md", 19 | "package.json", 20 | "types.d.ts" 21 | ], 22 | "scripts": { 23 | "dev": "vite build --watch", 24 | "build": "vite build" 25 | }, 26 | "keywords": [ 27 | "vitepress", 28 | "plugins", 29 | "component" 30 | ], 31 | "peerDependencies": { 32 | "vitepress": "*", 33 | "vue": "*" 34 | }, 35 | "devDependencies": { 36 | "sass": "^1.77.6" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/ConfigProvider/I18n.vue: -------------------------------------------------------------------------------- 1 | 13 | 27 | -------------------------------------------------------------------------------- /packages/components/Icon/Icon.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 37 | 38 | 41 | -------------------------------------------------------------------------------- /packages/components/Collapse/types.collapseItem.ts: -------------------------------------------------------------------------------- 1 | import type { CollapseItemName } from './types.collapse' 2 | 3 | export interface CollapseItemProps { 4 | /** 5 | * @property name 6 | * @type {string | number} 7 | * @description 唯一标识符 8 | * @default - 9 | */ 10 | name: CollapseItemName 11 | /** 12 | * @property title 13 | * @type string 14 | * @description 折叠面板标题 15 | */ 16 | title?: string 17 | /** 18 | * @property icon 19 | * @type string 20 | * @description 自定义展开图标 21 | * @default angle-right 22 | */ 23 | icon?: string 24 | /** 25 | * @property disabled 26 | * @type boolean 27 | * @description 是否禁用 28 | */ 29 | disabled?: boolean 30 | } 31 | 32 | export interface CollapseItemSlots { 33 | /** 34 | * @property default 35 | * @description CollapseItem 内容 36 | */ 37 | default: () => string 38 | /** 39 | * @property title 40 | * @description CollapseItem 标题 41 | */ 42 | title: () => string 43 | } 44 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Overlay/Basic.vue: -------------------------------------------------------------------------------- 1 | 16 | 28 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Overlay/Grid.vue: -------------------------------------------------------------------------------- 1 | 16 | 28 | -------------------------------------------------------------------------------- /packages/hooks/__test__/useClickOutside.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vi } from 'vitest' 2 | import { mount } from '@vue/test-utils' 3 | import { ref, defineComponent } from 'vue' 4 | 5 | import useClickOutside from '../useClickOutside' 6 | 7 | describe('hooks/useClickOutside', () => { 8 | it('should add `click-outside` listener', async () => { 9 | const target = ref() 10 | const btnRef = ref() 11 | 12 | const handler = vi.fn() 13 | 14 | mount( 15 | defineComponent({ 16 | setup() { 17 | useClickOutside(target, handler) 18 | return () => ( 19 |
20 | 21 |
22 | ) 23 | } 24 | }) 25 | ) 26 | 27 | await btnRef.value?.click() 28 | expect(handler).not.toHaveBeenCalled() 29 | 30 | await document.body.click() 31 | expect(handler).toHaveBeenCalledOnce() 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /packages/hooks/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { defineConfig } from 'vite' 3 | import { last, split, first, includes } from 'lodash-es' 4 | import { hooksPlugin as hooks } from '@pixel-ui/vite-plugins' 5 | 6 | import dts from 'vite-plugin-dts' 7 | 8 | export default defineConfig({ 9 | plugins: [ 10 | dts({ 11 | include: ['./**/*.ts'], 12 | exclude: ['./vite.config.ts'] 13 | }), 14 | hooks({ 15 | rmFiles: ['./dist'] 16 | }) 17 | ], 18 | build: { 19 | minify: false, 20 | lib: { 21 | entry: resolve(__dirname, './index.ts'), 22 | name: 'hooks', 23 | fileName: 'index', 24 | formats: ['es'] 25 | }, 26 | rollupOptions: { 27 | external: ['vue', 'lodash-es', 'vue3-i18n'], 28 | output: { 29 | manualChunks(id) { 30 | if (includes(id, '/packages/hooks/use')) 31 | return first(split(last(split(id, '/')), '.')) 32 | } 33 | } 34 | } 35 | } 36 | }) 37 | -------------------------------------------------------------------------------- /packages/components/Dropdown/types.dropdownItem.ts: -------------------------------------------------------------------------------- 1 | import type { VNode } from 'vue' 2 | 3 | export type DropdownCommand = string | number 4 | 5 | export interface DropdownItemProps { 6 | /** 7 | * @property command 8 | * @type {string | number} 9 | * @description 菜单项指令 10 | * @default - 11 | */ 12 | command?: DropdownCommand 13 | /** 14 | * @property label 15 | * @type {string | VNode} 16 | * @description 菜单项内容 17 | * @default - 18 | */ 19 | label?: string | VNode 20 | /** 21 | * @property disabled 22 | * @type {boolean} 23 | * @description 菜单项是否禁用 24 | * @default false 25 | */ 26 | disabled?: boolean 27 | /** 28 | * @property divided 29 | * @type {boolean} 30 | * @description 菜单项是否分割 31 | * @default false 32 | */ 33 | divided?: boolean 34 | } 35 | 36 | export interface DropdownItemSlots { 37 | /** 38 | * @property default 39 | * @description 默认插槽,优先级高于`props.label` 40 | */ 41 | default: () => string 42 | } 43 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Button/Size.vue: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Collapse/Icon.vue: -------------------------------------------------------------------------------- 1 | 22 | 32 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Overlay/Preset1.vue: -------------------------------------------------------------------------------- 1 | 16 | 28 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/plugins/tooltip.ts: -------------------------------------------------------------------------------- 1 | import type { MarkdownRenderer } from 'vitepress' 2 | 3 | export default (md: MarkdownRenderer): void => { 4 | md.renderer.rules.tooltip = (tokens, idx) => { 5 | const token = tokens[idx] 6 | 7 | return `` 8 | } 9 | 10 | md.inline.ruler.before('emphasis', 'tooltip', (state, silent) => { 11 | const tooltipRegExp = /^\^\[([^\]]*)\](`[^`]*`)?/ 12 | const str = state.src.slice(state.pos, state.posMax) 13 | 14 | if (!tooltipRegExp.test(str)) return false 15 | if (silent) return true 16 | 17 | const result = str.match(tooltipRegExp) 18 | 19 | if (!result) return false 20 | 21 | const token = state.push('tooltip', 'tooltip', 0) 22 | token.content = result[1].replace(/\\\|/g, '|') 23 | token.info = (result[2] || '').replace(/^`(.*)`$/, '$1') 24 | token.level = state.level 25 | state.pos += result[0].length 26 | 27 | return true 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /packages/docs/storybook/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel-ui/storybook", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "storybook": "storybook dev -p 6006", 8 | "build-storybook": "storybook build", 9 | "prettier": "prettier --write ." 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "packageManager": "pnpm@10.4.1", 15 | "devDependencies": { 16 | "@chromatic-com/storybook": "3", 17 | "@storybook/addon-actions": "^8.6.8", 18 | "@storybook/addon-essentials": "8.6.7", 19 | "@storybook/addon-onboarding": "8.6.7", 20 | "@storybook/blocks": "8.6.7", 21 | "@storybook/experimental-addon-test": "8.6.7", 22 | "@storybook/test": "8.6.7", 23 | "@storybook/vue3": "8.6.7", 24 | "@storybook/vue3-vite": "8.6.7", 25 | "@vitest/browser": "^3.0.9", 26 | "@vitest/coverage-v8": "^3.0.9", 27 | "playwright": "^1.51.1", 28 | "storybook": "8.6.7", 29 | "vitest": "^3.0.9" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Collapse/Basic.vue: -------------------------------------------------------------------------------- 1 | 19 | 29 | -------------------------------------------------------------------------------- /packages/docs/vitepress/components/configProvider.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Config Provider 3 | description: ConfigProvider 组件文档 4 | 5 | next: 6 | link: /components/input 7 | text: Input 输入框 8 | 9 | prev: 10 | link: /components/text 11 | text: Text 文本 12 | --- 13 | 14 | # ConfigProvider 全局配置 15 | 16 | Config Provider 被用来提供全局的配置选项, 让你的配置能够在全局都能够被访问到。 17 | 18 | ## i18n 配置 19 | 20 | 通过 Config Provider 来配置多语言, 让你的应用可以随时切换语言。 21 | 22 | 语言包文件存放在 `packages/locale/lang` 目录下, 默认语言为 `en`, 当前支持的语言包有`en`、`zhCN`、`zhTW`、`ja` 23 | 24 | :::tip 25 | Config Provider 还支持拓展翻译文本对象, 通过配置一个类型为 `TranslatePair` 的属性 `extendsI18nMsg` 实现, 具体格式参考语言包文件解构 26 | ::: 27 | 28 | :::preview 29 | demo-preview=../demo/ConfigProvider/I18n.vue 30 | ::: 31 | 32 | ## 实验性功能 33 | 34 | 在本节中, 您可以学习如何使用 Config Provider 来提供实验性功能。 现在, 我们还没有添加任何实验性功能, 但在未来的规划中, 我们将添加一些实验性功能。 您可以使用此配置来管理这些功能。 35 | 36 | ## API_Table插件测试 37 | 38 | :::danger 39 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 40 | ::: 41 | 42 | ::: api-table src=components/ConfigProvider/types.ts 43 | ::: 44 | 45 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Progress/Color.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 34 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Collapse/Accordion.vue: -------------------------------------------------------------------------------- 1 | 19 | 29 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Collapse/Disabled.vue: -------------------------------------------------------------------------------- 1 | 19 | 29 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Dropdown/HideOnClick.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 34 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Overlay/Color.vue: -------------------------------------------------------------------------------- 1 | 20 | 32 | -------------------------------------------------------------------------------- /packages/components/EyeDropper/EyeDropper.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { withInstall } from '@pixel-ui/utils' 3 | import { PxEyeDropper } from '.' 4 | 5 | import EyeDropper from './EyeDropper.vue' 6 | 7 | describe('EyeDropper/index', () => { 8 | // 测试 withInstall 函数是否被正确应用 9 | it('should be exported with withInstall()', () => { 10 | expect(PxEyeDropper.install).toBeDefined() 11 | }) 12 | 13 | // 测试组件是否被正确导出 14 | it('component should be exported', () => { 15 | expect(PxEyeDropper).toBe(EyeDropper) 16 | }) 17 | 18 | // 可选: 测试 withInstall 是否增强了组件功能 19 | it('should enhance EyeDropper component', () => { 20 | const enhancedEyeDropper = withInstall(EyeDropper) 21 | expect(enhancedEyeDropper).toBe(PxEyeDropper) 22 | }) 23 | 24 | // 可选: 如果 withInstall 函数有特定的行为或属性, 确保它们被正确应用 25 | it('should apply specific enhance', () => { 26 | const enhancedEyeDropper = withInstall(EyeDropper) 27 | // eg: withInstall 增加了一个特定的方法或属性 28 | expect(enhancedEyeDropper).toHaveProperty('install') 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /packages/docs/storybook/.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from '@storybook/vue3-vite' 2 | import { mergeConfig } from 'vite' 3 | import { fileURLToPath, URL } from 'node:url' 4 | 5 | const config: StorybookConfig = { 6 | stories: [ 7 | '../stories/**/*.mdx', 8 | '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)' 9 | ], 10 | addons: [ 11 | '@storybook/addon-essentials', 12 | '@storybook/addon-onboarding', 13 | '@storybook/experimental-addon-test' 14 | ], 15 | framework: { 16 | name: '@storybook/vue3-vite', 17 | options: { 18 | // docgen: 'vue-component-meta' 19 | } 20 | }, 21 | async viteFinal(config) { 22 | return mergeConfig(config, { 23 | resolve: { 24 | alias: { 25 | '@pixel-ui/components': fileURLToPath( 26 | new URL('../../../components', import.meta.url) 27 | ) 28 | } 29 | }, 30 | define: { 31 | ...(config.define || {}), 32 | TEST: false // 在 Storybook 环境中显式定义 TEST 33 | } 34 | }) 35 | } 36 | } 37 | export default config 38 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Progress/Indeterminate.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 43 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/icons/code-open.vue: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /packages/utils/__tests__/error.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vi } from 'vitest' 2 | 3 | import { throwError, debugWarn, PxUIError } from '../error' 4 | 5 | describe('error', () => { 6 | it('throwError should be worked', () => { 7 | expect(() => { 8 | throwError('scope', 'msg') 9 | }).toThrowError('[scope]: msg') 10 | }) 11 | it('debugWarn should be worked', () => { 12 | const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) 13 | debugWarn('scope', 'msg') 14 | debugWarn(new SyntaxError('custom error')) 15 | expect(warn.mock.calls).toMatchInlineSnapshot(` 16 | [ 17 | [ 18 | [PxUIError: [scope]: msg], 19 | ], 20 | [ 21 | [SyntaxError: custom error], 22 | ], 23 | ] 24 | `) 25 | }) 26 | it('PxUIError should extract message from Error object', () => { 27 | const originalError = new Error('original message') 28 | const pxError = new PxUIError(originalError) 29 | expect(pxError.message).toBe('original message') 30 | expect(pxError.name).toBe('PxUIError') 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "compilerOptions": { 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "module": "ESNext", 7 | "lib": [ 8 | "ES2020", 9 | "DOM", 10 | "DOM.Iterable" 11 | ], 12 | "skipLibCheck": true, 13 | /* Bundler mode */ 14 | "moduleResolution": "node", 15 | "allowImportingTsExtensions": true, 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "noEmit": true, 19 | "jsx": "preserve", 20 | "jsxImportSource": "vue", 21 | /* Linting */ 22 | "strict": true, 23 | "noUnusedLocals": true, 24 | "noUnusedParameters": true, 25 | "noFallthroughCasesInSwitch": true, 26 | "noUncheckedSideEffectImports": true, 27 | "paths": { 28 | "@pixel-ui/components": [ 29 | "./packages/components" 30 | ] 31 | } 32 | }, 33 | "include": [ 34 | "env.d.ts", 35 | "packages/**/*.ts", 36 | "packages/**/*.tsx", 37 | "packages/**/*.vue", 38 | "packages/**/types/*.d.ts", 39 | "vitest.config.ts" 40 | ] 41 | } -------------------------------------------------------------------------------- /packages/hooks/__test__/useId.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect, beforeEach } from 'vitest' 2 | import { useId } from '../useId' 3 | 4 | describe('useId', () => { 5 | beforeEach(() => { 6 | //! 重置 defaultIdInjection.current (需要导出 current 才能重置) 7 | //! 但当前 defaultIdInjection 是私有变量,无法在测试中重置 8 | //! 所以测试中避免依赖 current 的精确值 9 | }) 10 | 11 | it('should return a computed ref', () => { 12 | const id = useId() 13 | expect(id.value).toMatch(/^px-\d+-0}$/) 14 | }) 15 | 16 | it('should increment on access (computed re-eval)', () => { 17 | const id1 = useId() 18 | const first = id1.value 19 | const second = id1.value // still same because computed doesn't reevaluate unless deps change 20 | expect(first).toBe(second) 21 | }) 22 | 23 | it('should support custom namespace', () => { 24 | const id = useId('custom') 25 | expect(id.value).toMatch(/^custom-\d+-\d+}$/) 26 | }) 27 | 28 | it('should generate different ids on multiple calls', () => { 29 | const id1 = useId() 30 | const id2 = useId() 31 | expect(id1.value).not.toBe(id2.value) 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/vitepress/components/globals/vp-api-typing.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 27 | 48 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Collapse/Title.vue: -------------------------------------------------------------------------------- 1 | 23 | 33 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Progress/Striped.vue: -------------------------------------------------------------------------------- 1 | 48 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tag/Size.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 44 | 45 | 50 | -------------------------------------------------------------------------------- /packages/hooks/useLocale.ts: -------------------------------------------------------------------------------- 1 | import { computed, inject, ref, unref, type Ref } from 'vue' 2 | import { omit } from 'lodash-es' 3 | import { createI18n, i18nSymbol, type I18nInstance } from 'vue3-i18n' 4 | import English from '@pixel-ui/locale/lang/en' 5 | 6 | import type { Language } from '@pixel-ui/locale' 7 | 8 | // const omitInstall = (i18n: I18nInstance) => omit(i18n, ['install']) 9 | const omitInstall = (i18n: I18nInstance): Omit => 10 | omit(i18n, ['install']) as Omit 11 | 12 | export const useLocale = (localeOverrides?: Ref) => { 13 | if (!localeOverrides) { 14 | const i18n: Ref = 15 | inject(i18nSymbol) ?? 16 | ref(createI18n({ locale: English.name, messages: { en: English } })) 17 | 18 | return computed(() => omitInstall(unref(i18n))) 19 | } 20 | 21 | return computed(() => 22 | omitInstall( 23 | createI18n({ 24 | locale: localeOverrides.value.name, 25 | messages: { 26 | en: English, 27 | [localeOverrides.value.name]: localeOverrides.value 28 | } 29 | }) 30 | ) 31 | ) 32 | } 33 | 34 | export default useLocale 35 | -------------------------------------------------------------------------------- /packages/components/Card/Card.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 41 | 42 | 45 | -------------------------------------------------------------------------------- /libs/vitepress-api-table/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vitepress-api-table", 3 | "version": "0.0.1", 4 | "private": true, 5 | "type": "module", 6 | "main": "./.dist/index.cjs", 7 | "module": "./.dist/index.mjs", 8 | "types": "./.dist/index.d.ts", 9 | "exports": { 10 | ".": { 11 | "import": "./.dist/index.mjs", 12 | "require": "./.dist/index.cjs" 13 | } 14 | }, 15 | "files": [ 16 | ".dist", 17 | "README.md", 18 | "package.json" 19 | ], 20 | "scripts": { 21 | "dev": "rollup --config rollup.config.ts --watch", 22 | "build": "rollup --config rollup.config.ts --configPlugin typescript" 23 | }, 24 | "peerDependencies": { 25 | "markdown-it-container": "^3.0.0", 26 | "vitepress": "*", 27 | "vue": "*" 28 | }, 29 | "devDependencies": { 30 | "@rollup/plugin-typescript": "^11.1.6", 31 | "@types/markdown-it": "^13.0.8", 32 | "@types/markdown-it-container": "^2.0.10", 33 | "rollup": "^4.18.0", 34 | "rollup-plugin-dts": "^6.1.1", 35 | "tslib": "^2.6.3" 36 | }, 37 | "dependencies": { 38 | "markdown-it": "^14.1.0", 39 | "markdown-it-anchor": "^9.2.0", 40 | "markdown-it-container": "^3.0.0" 41 | } 42 | } -------------------------------------------------------------------------------- /packages/core/components.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PxButton, 3 | PxButtonGroup, 4 | PxIcon, 5 | PxCard, 6 | PxText, 7 | PxCollapse, 8 | PxCollapseItem, 9 | PxAlert, 10 | PxAnimationFrame, 11 | PxBadge, 12 | PxProgress, 13 | PxTooltip, 14 | PxPopconfirm, 15 | PxDropdown, 16 | PxDropdownItem, 17 | PxImage, 18 | PxPixelIt, 19 | PxTag, 20 | PxConfigProvider, 21 | PxMessage, 22 | PxNotification, 23 | PxInput, 24 | PxOverlay, 25 | PxMessageBox, 26 | PxLoading, 27 | PxSwitch, 28 | PxEyeDropper 29 | } from '@pixel-ui/components' 30 | import type { Plugin } from 'vue' 31 | 32 | // export an array of components with install method 33 | export default [ 34 | PxButton, 35 | PxButtonGroup, 36 | PxIcon, 37 | PxCard, 38 | PxText, 39 | PxCollapse, 40 | PxCollapseItem, 41 | PxAlert, 42 | PxAnimationFrame, 43 | PxBadge, 44 | PxProgress, 45 | PxTooltip, 46 | PxPopconfirm, 47 | PxDropdown, 48 | PxDropdownItem, 49 | PxImage, 50 | PxPixelIt, 51 | PxTag, 52 | PxConfigProvider, 53 | PxMessage, 54 | PxNotification, 55 | PxInput, 56 | PxOverlay, 57 | PxMessageBox, 58 | PxLoading, 59 | PxSwitch, 60 | PxEyeDropper 61 | ] as Plugin[] 62 | -------------------------------------------------------------------------------- /packages/utils/__tests__/style.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vi } from 'vitest' 2 | 3 | import { addUnit } from '../style' 4 | 5 | describe('style', () => { 6 | it('addUnit should add unit to number value', () => { 7 | expect(addUnit(10)).toBe('10px') 8 | }) 9 | 10 | it('addUnit should add unit to string value', () => { 11 | expect(addUnit('10')).toBe('10px') 12 | }) 13 | 14 | it('addUnit should not add unit to string value with unit', () => { 15 | expect(addUnit('10px')).toBe('10px') 16 | }) 17 | 18 | it('addUnit should not add unit to string value with unit', () => { 19 | expect(addUnit('10%')).toBe('10%') 20 | }) 21 | 22 | // 空值 23 | it('addUnit should not add unit to empty value', () => { 24 | expect(addUnit('')).toBe('') 25 | }) 26 | 27 | // 非法输入 28 | it('addUnit should not add unit to illegal value', () => { 29 | const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) 30 | addUnit(true as any) 31 | expect(warn.mock.calls).toMatchInlineSnapshot(` 32 | [ 33 | [ 34 | [PxUIError: [utils/style]: binding value must be a string or number], 35 | ], 36 | ] 37 | `) 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /packages/components/Collapse/transitionEvents.ts: -------------------------------------------------------------------------------- 1 | const _setHeightZero = (el: HTMLElement) => (el.style.height = '0px') 2 | 3 | const _setHeightScroll = (el: HTMLElement) => 4 | (el.style.height = `${el.scrollHeight}px`) 5 | 6 | const _setHeightEmpty = (el: HTMLElement) => (el.style.height = '') 7 | 8 | const _setOverflowHidden = (el: HTMLElement) => (el.style.overflow = 'hidden') 9 | 10 | const _setOverflowEmpty = (el: HTMLElement) => (el.style.overflow = '') 11 | 12 | type TransitionKey = 13 | | 'beforeEnter' 14 | | 'enter' 15 | | 'afterEnter' 16 | | 'beforeLeave' 17 | | 'leave' 18 | | 'afterLeave' 19 | 20 | const transitionEvents: Record void> = { 21 | beforeEnter(el) { 22 | _setHeightZero(el) 23 | _setOverflowHidden(el) 24 | }, 25 | enter: (el) => _setHeightScroll(el), 26 | afterEnter(el) { 27 | _setHeightEmpty(el) 28 | _setOverflowEmpty(el) 29 | }, 30 | beforeLeave(el) { 31 | _setHeightScroll(el) 32 | _setOverflowHidden(el) 33 | }, 34 | leave: (el) => _setHeightZero(el), 35 | afterLeave(el) { 36 | _setHeightEmpty(el) 37 | _setOverflowEmpty(el) 38 | } 39 | } 40 | 41 | export default transitionEvents 42 | -------------------------------------------------------------------------------- /packages/docs/vitepress/components/eyeDropper.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: EyeDropper 取色器 3 | description: EyeDropper 组件文档 4 | 5 | next: 6 | link: /components/image 7 | text: Image 像素滤镜 8 | 9 | prev: 10 | link: /components/animationFrame 11 | text: AnimationFrame 动画帧 12 | --- 13 | 14 | # EyeDropper 取色器 15 | 16 | EyeDropper 允许用户从屏幕中选择颜色 17 | 18 | ## 基础用法 19 | 20 | 通过 `onChange` 监听颜色选择, 通常搭配 `v-slot` 插槽暴露的方法使用 21 | 22 | :::preview 23 | demo-preview=../demo/EyeDropper/Basic.vue 24 | ::: 25 | 26 | ## API_Table插件测试 27 | 28 | :::danger 29 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 30 | ::: 31 | 32 | ::: api-table src=components/EyeDropper/types.ts 33 | ::: 34 | 35 | ```ts 36 | /** 37 | * EyeDropper 支持的 open 方法参数 38 | */ 39 | export interface EyeDropperOpenOptions { 40 | /** 41 | * @property signal 42 | * @description 可选的 AbortSignal, 用于中止操作 43 | * @type AbortSignal 44 | * @default undefined 45 | */ 46 | signal?: AbortSignal 47 | } 48 | 49 | /** 50 | * EyeDropper open 方法返回值 51 | */ 52 | export interface EyeDropperResult { 53 | /** 54 | * @property sRGBHex 55 | * @description 返回的选中颜色值(十六进制) 56 | * @type string 57 | */ 58 | sRGBHex: string 59 | } 60 | ``` 61 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Notification/Position.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 42 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/styles/various.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --component-preview-bg: var(--vp-c-bg); 3 | --component-preview-soft: var(--vp-c-bg-soft); 4 | --component-preview-mute: var(--vp-c-bg-mute); 5 | --component-preview-border: rgb(240, 240, 240); 6 | --component-preview-text-1: var(--vp-c-text-1); 7 | --component-preview-text-2: var(--vp-c-text-2); 8 | --component-preview-text-3: var(--vp-c-text-3); 9 | --component-preview-text-4: var(--vp-c-text-4); 10 | --component-preview-code-block-bg: #343030; 11 | --component-preview-primary-color: var(--vp-c-brand); 12 | } 13 | 14 | .dark:root { 15 | --component-preview-bg: var(--vp-c-bg); 16 | --component-preview-soft: var(--vp-c-bg-soft); 17 | --component-preview-mute: var(--vp-c-bg-mute); 18 | --component-preview-border: rgb(240, 240, 240, 0.1); 19 | --component-preview-text-1: var(--vp-c-text-1); 20 | --component-preview-text-2: var(--vp-c-text-2); 21 | --component-preview-text-3: var(--vp-c-text-3); 22 | --component-preview-text-4: var(--vp-c-text-4); 23 | --component-preview-code-block-bg: #282626; 24 | --component-preview-primary-color: var(--vp-c-brand); 25 | } 26 | 27 | $defaultPrefix: 'vitepress-demo-preview'; 28 | -------------------------------------------------------------------------------- /packages/docs/vitepress/components/text.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Text 3 | description: Text 组件文档 4 | 5 | next: 6 | link: /components/configProvider 7 | text: ConfigProvider 全局配置 8 | 9 | prev: 10 | link: /components/overlay 11 | text: Overlay 遮罩层 12 | --- 13 | 14 | # Text 文本 15 | 16 | 文本的常见操作 17 | 18 | ## 基础用法 19 | 20 | 用 `type` 属性设置 Text 类型, `bold` 属性设置**粗体** 21 | 22 | ::: preview 23 | demo-preview=../demo/Text/Basic.vue 24 | ::: 25 | 26 | ## 尺寸 27 | 28 | 使用 `size` 属性设置 Text 尺寸, 默认大小为 `14px`, 传入值默认为 `px` 29 | 30 | ::: preview 31 | demo-preview=../demo/Text/Size.vue 32 | ::: 33 | 34 | ## 颜色 35 | 36 | 使用 `color` 属性设置 Text 颜色 37 | 38 | ::: preview 39 | demo-preview=../demo/Text/Color.vue 40 | ::: 41 | 42 | ## 对齐方式 & 紧凑 43 | 44 | 使用 `align` 属性设置 Text 对齐方式, 可选值为 `left`, `center`, `right`, 使用 `compact` 属性设置 Text 是否紧凑 45 | 46 | ::: preview 47 | demo-preview=../demo/Text/Align.vue 48 | ::: 49 | 50 | ## Tag 51 | 52 | 可以自定义元素标签。例如, 按钮, div, 路由链接, nuxt 链接。 53 | 54 | ::: preview 55 | demo-preview=../demo/Text/Tag.vue 56 | ::: 57 | 58 | ## API_Table插件测试 59 | 60 | :::danger 61 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 62 | ::: 63 | 64 | ::: api-table src=components/Text/types.ts 65 | ::: 66 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.vitepress/config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress' 2 | import { nav, sidebar, mdPlugin, viteConfig, head } from './configs' 3 | 4 | export default defineConfig({ 5 | title: 'Pixel UI', 6 | description: '基于CSS_Houdini的像素风组件库🐱', 7 | base: '/pixel-ui/', 8 | appearance: false, 9 | head, 10 | themeConfig: { 11 | // 导航栏 12 | nav, 13 | // 侧边栏 14 | sidebar, 15 | logo: '/images/homelogo.png', 16 | search: { 17 | provider: 'local' 18 | }, 19 | outline: { 20 | level: [2, 3], 21 | label: 'CONTENTS' 22 | }, 23 | socialLinks: [ 24 | { icon: 'github', link: 'https://github.com/maomentai817/pixel-ui' } 25 | ] 26 | }, 27 | markdown: { 28 | config: (md) => mdPlugin(md) 29 | }, 30 | transformHead({ assets }) { 31 | // 字体匹配 32 | const fontFiles = assets.filter((file) => 33 | /(PS2P|Zpix)\.\w+\.ttf$/.test(file) 34 | ) 35 | 36 | return fontFiles.map((file) => [ 37 | 'link', 38 | { 39 | rel: 'preload', 40 | href: file, 41 | as: 'font', 42 | type: 'font/woff2', 43 | crossorigin: '' 44 | } 45 | ]) 46 | }, 47 | vite: viteConfig 48 | }) 49 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Badge/CustomColor.vue: -------------------------------------------------------------------------------- 1 | 20 | 39 | -------------------------------------------------------------------------------- /packages/hooks/__test__/useLocale.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { ref, nextTick } from 'vue' 3 | import { useLocale } from '../useLocale' 4 | import { mount } from '@vue/test-utils' 5 | // import English from '@pixel-ui/locale/lang/en' 6 | 7 | describe('useLocale', () => { 8 | it('returns default i18n when no overrides provided', () => { 9 | const wrapper = mount({ 10 | setup() { 11 | const i18n = useLocale() 12 | return () =>
{i18n.value.t('el.popconfirm.cancelButtonText')}
13 | } 14 | }) 15 | 16 | expect(wrapper.text()).toBe('No') 17 | }) 18 | 19 | it('returns overridden i18n when localeOverrides is provided', async () => { 20 | const zhCN = { 21 | name: 'zh-cn', 22 | el: { 23 | popconfirm: { 24 | cancelButtonText: '取消' 25 | } 26 | } 27 | } 28 | 29 | const overrideRef = ref(zhCN) 30 | 31 | const wrapper = mount({ 32 | setup() { 33 | const i18n = useLocale(overrideRef) 34 | return () =>
{i18n.value.t('el.popconfirm.cancelButtonText')}
35 | } 36 | }) 37 | 38 | await nextTick() 39 | expect(wrapper.text()).toBe('取消') 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Button/Group.vue: -------------------------------------------------------------------------------- 1 | 38 | -------------------------------------------------------------------------------- /packages/utils/__tests__/vnode.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { mount } from '@vue/test-utils' 3 | import { h } from 'vue' 4 | import { RenderVNode } from '../' 5 | 6 | describe('RenderVNode', () => { 7 | it('renders a string vnode', () => { 8 | const wrapper = mount(RenderVNode, { 9 | props: { 10 | vNode: 'Hello Pixel UI' 11 | } 12 | }) 13 | expect(wrapper.text()).toBe('Hello Pixel UI') 14 | }) 15 | 16 | it('renders a VNode object', () => { 17 | const wrapper = mount(RenderVNode, { 18 | props: { 19 | vNode: h('span', { class: 'custom' }, 'Inside Span') 20 | } 21 | }) 22 | const span = wrapper.find('span') 23 | expect(span.exists()).toBe(true) 24 | expect(span.text()).toBe('Inside Span') 25 | expect(span.classes()).toContain('custom') 26 | }) 27 | 28 | it('renders from a function returning vnode', () => { 29 | const wrapper = mount(RenderVNode, { 30 | props: { 31 | vNode: () => h('div', { class: 'dynamic' }, 'Generated VNode') 32 | } 33 | }) 34 | const div = wrapper.find('div.dynamic') 35 | expect(div.exists()).toBe(true) 36 | expect(div.text()).toBe('Generated VNode') 37 | }) 38 | }) 39 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "compilerOptions": { 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "module": "ESNext", 7 | "lib": [ 8 | "ES2020", 9 | "DOM", 10 | "DOM.Iterable" 11 | ], 12 | "skipLibCheck": true, 13 | /* Bundler mode */ 14 | "moduleResolution": "bundler", 15 | "allowImportingTsExtensions": true, 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "noEmit": true, 19 | "jsx": "preserve", 20 | "jsxImportSource": "vue", 21 | /* Linting */ 22 | "strict": true, 23 | "noUnusedLocals": true, 24 | "noUnusedParameters": true, 25 | "noFallthroughCasesInSwitch": true, 26 | "types": [ 27 | "node" 28 | ], 29 | "baseUrl": "./", 30 | "paths": { 31 | "@pixel-ui/components": [ 32 | "./packages/components" 33 | ] 34 | } 35 | }, 36 | "include": [ 37 | "env.d.ts", 38 | "packages/**/types/*.d.ts", 39 | "packages/core/index.ts", 40 | "packages/hooks/**/*.ts", 41 | "packages/utils/**/*.ts", 42 | "packages/components/**/*.ts" 43 | ], 44 | "exclude": [ 45 | "packages/components/vitest.config.ts" 46 | ] 47 | } -------------------------------------------------------------------------------- /packages/components/Card/types.ts: -------------------------------------------------------------------------------- 1 | export interface CardProps { 2 | /** 3 | * @property hoverable 4 | * @type boolean 5 | * @description 是否启用Hover效果 6 | * @default false 7 | */ 8 | hoverable?: boolean 9 | /** 10 | * @property round 11 | * @type boolean 12 | * @description 是否启用圆角效果 13 | * @default false 14 | */ 15 | round?: boolean 16 | /** 17 | * @property circle 18 | * @type boolean 19 | * @description 是否启用圆形效果 20 | * @default false 21 | */ 22 | circle?: boolean 23 | /** 24 | * @property stamp 25 | * @type boolean 26 | * @description 是否启用标签效果 27 | * @default false 28 | */ 29 | stamp?: boolean 30 | } 31 | 32 | export interface CardSlots { 33 | /** 34 | * @property default 35 | * @description 默认插槽,卡片内容 36 | */ 37 | default: () => string 38 | /** 39 | * @property header 40 | * @description 卡片标题内容 41 | */ 42 | header: () => string 43 | /** 44 | * @property footer 45 | * @description 卡片底部内容 46 | */ 47 | footer: () => string 48 | /** 49 | * @property prepend 50 | * @description 卡片前置内容 51 | */ 52 | prepend: () => string 53 | /** 54 | * @property append 55 | * @description 卡片后置内容 56 | */ 57 | append: () => string 58 | } 59 | -------------------------------------------------------------------------------- /packages/docs/vitepress/components/image.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Image 图片像素滤镜 3 | description: Image 组件文档 4 | 5 | next: 6 | link: /components/pixelit 7 | text: Pixelit 图片像素化 8 | 9 | prev: 10 | link: /components/eyeDropper 11 | text: EyeDropper 取色器 12 | --- 13 | 14 | # Image 图片像素滤镜 15 | 16 | 一张图片, 为其提供像素滤镜效果, 支持颜色数量压缩、抗锯齿去除、背景色保留、网格线绘制等功能 17 | 18 | ## 基础功能 19 | 20 | 通过 `src` 属性指定图片路径, 组件会在 Canvas 上渲染像素滤镜效果 21 | 22 | :::tip 23 | 当前组件提供 `width`、`height` 来设置 Canvas 及组件盒子的宽高, 默认为图片的宽高。但由于缩放渲染问题, 宽高设置过小可能会导致图片模糊, 请酌情使用或按比例缩放 24 | 25 | 新增 `scale` 属性来设置图片缩放比例, 当原图尺寸过大时, 强烈建议设置 `scale` 控制 26 | ::: 27 | 28 | :::preview 29 | demo-preview=../demo/Image/Basic.vue 30 | ::: 31 | 32 | ## 自定义参数 33 | 34 | 你可以通过调整 `block-size`、`color-count` 等属性来自定义像素滤镜的效果 35 | 36 | :::preview 37 | demo-preview=../demo/Image/Custom.vue 38 | ::: 39 | 40 | ## 网格模式 41 | 42 | 通过设置 `showGrid` 控制是否显示 canvas 网格 43 | 44 | :::preview 45 | demo-preview=../demo/Image/Grid.vue 46 | ::: 47 | 48 | ## 在线体验 49 | 50 | 提供在线演练场, 上传图片, 快速体验 51 | 52 | :::preview 53 | demo-preview=../demo/Image/Playground.vue 54 | ::: 55 | 56 | ## API_Table插件测试 57 | 58 | :::danger 59 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 60 | ::: 61 | 62 | ::: api-table src=components/Image/types.ts 63 | ::: -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Alert/Iron.vue: -------------------------------------------------------------------------------- 1 | 29 | 43 | -------------------------------------------------------------------------------- /packages/docs/vitepress/components/collapse.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Collapse 3 | description: Collapse 组件文档 4 | 5 | next: 6 | link: /components/progress 7 | text: Progress 进度条 8 | 9 | prev: 10 | link: /components/card 11 | text: Card 卡片 12 | --- 13 | 14 | # Collapse 折叠面板 15 | 16 | 通过折叠面板收纳内容区域 17 | 18 | ## 基础用法 19 | 20 | 可同时展开多个面板, 面板之间互不影响 21 | 22 | ::: preview 23 | demo-preview=../demo/Collapse/Basic.vue 24 | ::: 25 | 26 | ## 手风琴效果 27 | 28 | 每次只能展开一个面板 29 | 30 | 通过 `accordion` 属性来设置是否以手风琴模式显示 31 | 32 | :::preview 33 | demo-preview=../demo/Collapse/Accordion.vue 34 | ::: 35 | 36 | ## 自定义面板标题 37 | 38 | 除了可以通过 `title` 属性来设置标题内容, 也可以通过具名 `title` 插槽来自定义标题内容 39 | 40 | :::preview 41 | demo-preview=../demo/Collapse/Title.vue 42 | ::: 43 | 44 | ## 禁用面板 45 | 46 | 通过 `disabled` 属性来设置是否禁用面板 47 | 48 | :::preview 49 | demo-preview=../demo/Collapse/Disabled.vue 50 | ::: 51 | 52 | ## 自定义展开图标 53 | 54 | 通过 `icon` 属性来设置自定义展开图标 55 | 56 | :::preview 57 | demo-preview=../demo/Collapse/Icon.vue 58 | ::: 59 | 60 | ## API_Table插件测试 61 | 62 | :::danger 63 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 64 | ::: 65 | 66 | ::: api-table src=components/Collapse/types.collapse.ts 67 | ::: 68 | 69 | ::: api-table src=components/Collapse/types.collapseItem.ts 70 | ::: -------------------------------------------------------------------------------- /packages/docs/vitepress/components/tag.md: -------------------------------------------------------------------------------- 1 | # Tag 标签 2 | 3 | 用于标记和分类。 4 | 5 | ## 基础用法 6 | 7 | 基础的标签用法, 可以通过`type`属性设置不同的标签类型。 8 | 9 | :::preview 10 | demo-preview=../demo/Tag/Basic.vue 11 | ::: 12 | 13 | ## 可关闭标签 14 | 15 | 设置`closable`属性可以定义一个标签是否可关闭, 关闭时会触发`close`事件。 16 | 17 | :::preview 18 | demo-preview=../demo/Tag/Closable.vue 19 | ::: 20 | 21 | ## 不同尺寸 22 | 23 | Tag组件提供了三种不同尺寸, 用于不同场景。 24 | 25 | :::preview 26 | demo-preview=../demo/Tag/Size.vue 27 | ::: 28 | 29 | ## 主题 30 | 31 | Tag 组件提供了三种主题:`light` (亮色), `dark` (暗色), `plain` (描边) 32 | 33 | 通过设置 `effect` 属性来改变主题, 默认为 `light`。 34 | 35 | :::preview 36 | demo-preview=../demo/Tag/Effect.vue 37 | ::: 38 | 39 | ## 圆角标签 40 | 41 | Tag 提供了圆角边框, 通过设置 `round`, `circle`, `chubby` 属性来改变标签的形状, 默认为 `false`。 42 | 43 | :::preview 44 | demo-preview=../demo/Tag/Round.vue 45 | ::: 46 | 47 | ## 禁用状态 48 | 49 | 可以使用`disabled`属性来定义标签是否被禁用。 50 | 51 | :::preview 52 | demo-preview=../demo/Tag/Disabled.vue 53 | ::: 54 | 55 | ## 自定义颜色 56 | 57 | 可以通过`color`属性设置标签的自定义颜色。 58 | 59 | :::preview 60 | demo-preview=../demo/Tag/CustomColor.vue 61 | ::: 62 | 63 | ## API_Table插件测试 64 | 65 | :::danger 66 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 67 | ::: 68 | 69 | ::: api-table src=components/Tag/types.ts 70 | ::: 71 | -------------------------------------------------------------------------------- /packages/docs/vitepress/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution') 3 | 4 | module.exports = { 5 | root: true, 6 | extends: [ 7 | 'plugin:vue/vue3-essential', 8 | '@vue/eslint-config-typescript/recommended', 9 | 'eslint:recommended', 10 | '@vue/eslint-config-prettier', 11 | '@unocss' 12 | ], 13 | parser: 'vue-eslint-parser', 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | parser: '@typescript-eslint/parser', 17 | sourceType: 'module', 18 | extraFileExtensions: ['.vue'] 19 | }, 20 | rules: { 21 | 'prettier/prettier': [ 22 | 'warn', 23 | { 24 | singleQuote: true, 25 | semi: false, 26 | printWidth: 80, 27 | trailingComma: 'none', 28 | endOfLine: 'auto' 29 | } 30 | ], 31 | 'vue/multi-word-component-names': 'off', 32 | 'no-unused-vars': [ 33 | 'error', 34 | { 35 | argsIgnorePattern: '^_' 36 | } 37 | ], 38 | 'vue/no-setup-props-destructure': ['off'], 39 | 'no-undef': 'error', 40 | 'vue/script-setup-uses-vars': 'error', 41 | '@typescript-eslint/no-explicit-any': 'off' 42 | }, 43 | env: { 44 | browser: true, 45 | es2021: true 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Dropdown/Manual.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 29 | 30 | 43 | -------------------------------------------------------------------------------- /packages/components/Dropdown/DropdownItem.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 43 | 44 | 47 | -------------------------------------------------------------------------------- /packages/hooks/useDisabledStyle.ts: -------------------------------------------------------------------------------- 1 | import { each, isFunction, cloneDeep, assign } from 'lodash-es' 2 | import { watchEffect, useSlots, getCurrentInstance, type VNode } from 'vue' 3 | 4 | // 递归遍历节点, 执行回调 5 | const _dfs = (nodes: VNode[], cb: (_node: VNode) => void) => 6 | each(nodes, (node) => { 7 | isFunction(cb) && cb(node) 8 | node.children && _dfs(node.children as VNode[], cb) 9 | }) 10 | 11 | export const useDisabledStyle = () => { 12 | const nodePropsMap = new Map() 13 | 14 | const instance = getCurrentInstance() 15 | const children = useSlots()?.default?.() 16 | 17 | watchEffect(() => { 18 | // 恢复节点样式 19 | if (!instance?.props.disabled) { 20 | _dfs(children ?? [], (node) => { 21 | if (!nodePropsMap.has(node)) return 22 | node.props = nodePropsMap.get(node) 23 | }) 24 | return 25 | } 26 | // disabled 状态, 深度遍历所有子节点, 设置禁用 27 | _dfs(children ?? [], (node) => { 28 | if (!node?.props) return 29 | 30 | nodePropsMap.set(node, cloneDeep(node.props)) 31 | node.props = assign(node?.props, { 32 | style: { 33 | cursor: 'not-allowed', 34 | color: 'var(--px-color-info)' 35 | } 36 | }) 37 | }) 38 | }) 39 | } 40 | 41 | export default useDisabledStyle 42 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Dropdown/Size.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 38 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/messages/index.ts: -------------------------------------------------------------------------------- 1 | import { ComponentPublicInstance, createApp } from 'vue' 2 | 3 | import MessageNotice from './message-notice.vue' 4 | 5 | const messageNoticeInstanceList: ComponentPublicInstance[] = [] 6 | 7 | const MessageNoticeService = { 8 | open: () => { 9 | // 创建一个div元素 10 | const messageBox = document.createElement('div') 11 | // 创建一个应用实例 12 | const messageApp = createApp(MessageNotice, { 13 | content: '复制成功!', 14 | close: () => { 15 | document.body.removeChild(messageBox) 16 | messageNoticeInstanceList.pop() 17 | messageApp.unmount() 18 | } 19 | }) 20 | const messageInstance = messageApp.mount(messageBox) 21 | document.body.appendChild(messageBox) 22 | const messageNoticeInstanceListLength = messageNoticeInstanceList.length 23 | const topHeight = 24 | messageNoticeInstanceListLength === 0 25 | ? 10 26 | : (messageNoticeInstanceListLength + 1) * 10 + messageNoticeInstanceListLength * 42 27 | // @ts-ignore 28 | messageInstance.setTopHeight(topHeight) 29 | // @ts-ignore 30 | messageInstance.setVisible(true) 31 | messageNoticeInstanceList.push(messageInstance) 32 | } 33 | } 34 | 35 | export { MessageNotice, MessageNoticeService } 36 | -------------------------------------------------------------------------------- /packages/core/printLogo.ts: -------------------------------------------------------------------------------- 1 | /* global DEV, PROD */ 2 | export default function () { 3 | if (PROD) { 4 | /* eslint-disable no-useless-escape */ 5 | const logo = ` 6 | ____________________________________________________________________________________ 7 | 8 | 9 | ███╗ ███╗███╗ ███╗████████╗ █████╗ ██╗███████╗ 10 | ████╗ ████║████╗ ████║╚══██╔══╝ ██╔══██╗███║╚════██║ 11 | ██╔████╔██║██╔████╔██║ ██║ ╚█████╔╝╚██║ ██╔╝ 12 | ██║╚██╔╝██║██║╚██╔╝██║ ██║ ██╔══██╗ ██║ ██╔╝ 13 | ██║ ╚═╝ ██║██║ ╚═╝ ██║ ██║ ╚█████╔╝ ██║ ██║ 14 | ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚════╝ ╚═╝ ╚═╝ 15 | 16 | ____________________________________________________________________________________ 17 | author:mmt817🐱 18 | ` 19 | 20 | const rainbowGradient = ` 21 | background: linear-gradient(135deg, orange 60%, cyan); 22 | background-clip: text; 23 | color: transparent; 24 | font-size: 16px; 25 | line-height: 1; 26 | font-family: "Courier New", ui-monospace, monospace; 27 | font-weight: 600; 28 | ` 29 | 30 | console.info(`%c${logo}`, rainbowGradient) 31 | } else if (DEV) { 32 | console.log('[PixelUI]:dev mode...') 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Dropdown/Event.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 30 | 31 | 40 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/MessageBox/Style.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 36 | 56 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Icon/Basic.vue: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /packages/components/types/worklet.d.ts: -------------------------------------------------------------------------------- 1 | // types/worklets.d.ts 2 | declare module '*.worklet.ts' { 3 | const content: string 4 | export default content 5 | } 6 | 7 | declare module '*.worklet.ts?worklet' { 8 | const workletUrl: string 9 | export default workletUrl 10 | } 11 | 12 | // Add support for JavaScript worklets 13 | declare module '*.worklet.js?url' { 14 | const content: string 15 | export default content 16 | } 17 | 18 | declare module '*.worklet.js?worklet' { 19 | const workletUrl: string 20 | export default workletUrl 21 | } 22 | 23 | // todo: worklet/ 类型声明 24 | interface CSSStyleValue { 25 | toString(): string 26 | } 27 | 28 | interface StylePropertyMap { 29 | get(_property: string): CSSStyleValue | undefined 30 | getAll(_property: string): CSSStyleValue[] 31 | has(_property: string): boolean 32 | } 33 | 34 | interface PaintSize { 35 | width: number 36 | height: number 37 | } 38 | 39 | interface PaintWorklet { 40 | paint( 41 | _ctx: PaintRenderingContext2D, 42 | _size: PaintSize, 43 | _props: StylePropertyMap 44 | ): void 45 | } 46 | 47 | declare let registerPaint: ( 48 | _name: string, 49 | _ctor: new () => PaintWorklet 50 | ) => void 51 | 52 | // PaintRenderingContext2D 实际上就是 CanvasRenderingContext2D 53 | type PaintRenderingContext2D = CanvasRenderingContext2D 54 | -------------------------------------------------------------------------------- /packages/docs/vitepress/components/animationFrame.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: AnimationFrame 3 | description: AnimationFrame 组件文档 4 | 5 | next: 6 | link: /components/eyeDropper 7 | text: EyeDropper 取色器 8 | 9 | prev: 10 | link: /components/tooltip 11 | text: Tooltip 文字提示 12 | --- 13 | 14 | # AnimationFrame 动画帧 15 | 16 | 提供 `stages` 控制 GIF 动画播放, 默认点击进行阶段跳转 17 | 18 | ## 基础用法 19 | 20 | 提供一张 GIF 图片, 默认完整播放 21 | 22 | :::preview 23 | demo-preview=../demo/AnimationFrame/Basic.vue 24 | ::: 25 | 26 | ## Loop 循环播放 27 | 28 | 通过 `loop` 属性控制是否循环播放 29 | 30 | :::preview 31 | demo-preview=../demo/AnimationFrame/Loop.vue 32 | ::: 33 | 34 | ## Stages 跳转阶段 35 | 36 | :::tip 37 | `stages` 属性类型为 `AnimationFrameStage[]` 38 | 39 | 其中 `AnimationFrameStage:{start:number;end:number;type:'loop'|'once'}` 40 | 41 | 点击切换动画阶段, 建议合理运用 GIF 分解工具查看对应帧 42 | ::: 43 | 44 | 通过 `stages` 属性控制 GIF 动画播放, 默认点击进行阶段跳转 45 | 46 | :::preview 47 | demo-preview=../demo/AnimationFrame/Stages.vue 48 | ::: 49 | 50 | ## API_Table插件测试 51 | 52 | :::danger 53 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 54 | ::: 55 | 56 | ::: api-table src=components/AnimationFrame/types.ts 57 | ::: 58 | 59 | ```ts 60 | type AnimationFrameType = 'loop' | 'once' 61 | 62 | interface AnimationFrameStage { 63 | start: number 64 | end: number 65 | type: AnimationFrameType 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /packages/docs/vitepress/components/popconfirm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Popconfirm 3 | description: Popconfirm 组件文档 4 | 5 | next: 6 | link: /components/tooltip 7 | text: Tooltip 文字提示 8 | 9 | prev: 10 | link: /components/notification 11 | text: Notification 通知 12 | --- 13 | 14 | # Popconfirm 气泡确认框 15 | 16 | 点击某个元素弹出一个简单的气泡确认框 17 | 18 | ## 展示位置 19 | 20 | Popconfirm 提供了 9 种展示位置 21 | 22 | 使用 `title` 属性来设置点击参考元素时显示的信息, 由 `placement` 属性来决定展示的方向: `[方向]-[对齐位置]`; 四个方向: `top`, `bottom`, `left`, `right`; 三种对齐位置: `start`, `end`, `null`, 默认为 null。 如 `placement="left-end"`, 则气泡确认框出现在目标元素左侧, 且气泡确认框的底部与目标元素底部对齐。 23 | 24 | ::: preview 25 | demo-preview=../demo/Popconfirm/Placement.vue 26 | ::: 27 | 28 | ## 基础用法 29 | 30 | Popconfirm 属性同 Tooltip 类似, 是基于 Tooltip 封装的拓展 31 | 32 | 在 Popconfirm 中, 只有 `title` 可用, `content` 属性无效。 33 | 34 | ::: preview 35 | demo-preview=../demo/Popconfirm/Basic.vue 36 | ::: 37 | 38 | ## 自定义弹出框内容 39 | 40 | 可以在 Popconfirm 中自定义内容 41 | 42 | ::: preview 43 | demo-preview=../demo/Popconfirm/Custom.vue 44 | ::: 45 | 46 | ## 多种让 Popconfirm 出现的方法 47 | 48 | 点击按钮触发事件 49 | 50 | ::: preview 51 | demo-preview=../demo/Popconfirm/Callback.vue 52 | ::: 53 | 54 | ## API_Table插件测试 55 | 56 | :::danger 57 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 58 | ::: 59 | 60 | ::: api-table src=components/Popconfirm/types.ts 61 | ::: 62 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/.dist/messages/message-notice.vue.d.ts: -------------------------------------------------------------------------------- 1 | interface MessageNotice { 2 | content: string; 3 | close: () => void; 4 | } 5 | declare const _default: import('vue').DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps, { 6 | content: string; 7 | }>, { 8 | setVisible: (value: boolean) => void; 9 | setTopHeight: (value: number) => void; 10 | }, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly, { 11 | content: string; 12 | }>>>, { 13 | content: string; 14 | }, {}>; 15 | export default _default; 16 | type __VLS_NonUndefinedable = T extends undefined ? never : T; 17 | type __VLS_TypePropsToRuntimeProps = { 18 | [K in keyof T]-?: {} extends Pick ? { 19 | type: import('vue').PropType<__VLS_NonUndefinedable>; 20 | } : { 21 | type: import('vue').PropType; 22 | required: true; 23 | }; 24 | }; 25 | type __VLS_WithDefaults = { 26 | [K in keyof Pick]: K extends keyof D ? __VLS_Prettify : P[K]; 29 | }; 30 | type __VLS_Prettify = { 31 | [K in keyof T]: T[K]; 32 | } & {}; 33 | -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Image/Custom.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 40 | -------------------------------------------------------------------------------- /packages/docs/vitepress/components/overlay.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Overlay 3 | description: Overlay 组件文档 4 | 5 | next: 6 | link: /components/text 7 | text: Text 文本 8 | 9 | prev: 10 | link: /components/icon 11 | text: Icon 图标 12 | --- 13 | 14 | # Overlay 遮罩层 15 | 16 | 向指定元素添加遮罩层, 常用于模态框、抽屉等组件背景。 17 | 18 | ## 基础用法 19 | 20 | 通过 `mask` 属性控制遮罩层**样式上的**显示隐藏, 通过 `zIndex` 属性设置遮罩层层级 21 | 22 | 设置在 `px-overlay` 上的 `attrs` 会被拦截, 自定义类名列表可通过 `overlayClass` 添加 23 | 24 | :::warning 25 | `mask` 属性仅控制**遮罩层显示**, 仅属于样式上的区分, 对于插槽内容不做处理 26 | 27 | 页面滚动的锁定与 `px-overlay` 卸载挂载关联, 建议使用 `v-if` 控制实例创建销毁 28 | ::: 29 | 30 | ::: preview 31 | demo-preview=../demo/Overlay/Basic.vue 32 | ::: 33 | 34 | ## 自定义颜色 35 | 36 | 通过 `color` 设置默认遮罩层颜色 37 | 38 | :::tip 39 | `grid`, `preset` 等预设装饰性遮罩层优先级高于 `color` 自定义颜色 40 | 41 | 其颜色通过 `--px-grid-color-1` 等属性修改 42 | ::: 43 | 44 | ::: preview 45 | demo-preview=../demo/Overlay/Color.vue 46 | ::: 47 | 48 | ## 网格背景-默认 49 | 50 | 通过 `grid` 属性设置网格背景 51 | 52 | ::: preview 53 | demo-preview=../demo/Overlay/Grid.vue 54 | ::: 55 | 56 | ## 网格背景-预设1 57 | 58 | 通过 `preset1` 预设网格背景-1, 同时可通过 `matte` 属性设置遮罩层 **哑光** 效果 59 | 60 | ::: preview 61 | demo-preview=../demo/Overlay/Preset1.vue 62 | ::: 63 | 64 | 65 | ## API_Table插件测试 66 | 67 | :::danger 68 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 69 | ::: 70 | 71 | ::: api-table src=components/Overlay/types.ts 72 | ::: -------------------------------------------------------------------------------- /packages/docs/vitepress/components/pixelit.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Pixelit 图片像素化 3 | description: Pixelit 组件文档 4 | 5 | next: 6 | link: /components/pixelit 7 | text: Pixelit 图片像素化 8 | 9 | prev: 10 | link: /components/animationFrame 11 | text: AniamtionFrame 动画帧 12 | --- 13 | 14 | # Pixelit 图片像素化 15 | 16 | Pixelit 用于将图片进行像素风格渲染。支持自定义缩放比例、灰度处理、调色板替换等 17 | 18 | :::tip 19 | 对于复杂图片, 相较于 [PxImage](/components/image) 组件, Pixelit 组件性能更高, 但对于纯色图片处理较差, 请合理使用 20 | ::: 21 | 22 | ## 基本用法 23 | 24 | 通过设置 `src` 属性指定原始图片地址, 组件会自动进行像素化处理 25 | 26 | :::preview 27 | demo-preview=../demo/Pixelit/Basic.vue 28 | ::: 29 | 30 | ## 图像尺寸 31 | 32 | 通过设置 `width`、`height` 属性来设置组件的宽高, 默认为图片的宽高。 33 | 34 | 提供 `aspect-ratio` 属性来设置组件的缩放, 默认为 `1` 35 | 36 | :::preview 37 | demo-preview=../demo/Pixelit/Size.vue 38 | ::: 39 | 40 | ## 灰度化 41 | 42 | 设置 `grayscale` 属性来对图片进行灰度处理 43 | 44 | :::preview 45 | demo-preview=../demo/Pixelit/Grayscale.vue 46 | ::: 47 | 48 | ## 调色板替换 49 | 50 | 通过 `palette` 属性可设置自定义颜色调色板 (二维 RGB 数组), 对图像颜色进行替换 51 | 52 | :::preview 53 | demo-preview=../demo/Pixelit/Palette.vue 54 | ::: 55 | 56 | ## 在线体验 57 | 58 | 提供在线演练场, 上传图片, 快速体验 59 | 60 | :::preview 61 | demo-preview=../demo/Pixelit/Playground.vue 62 | ::: 63 | 64 | ## API_Table插件测试 65 | 66 | :::danger 67 | 该插件基于 `markdown-it` 开发, 解析组件 `types.ts` 文件生成 API 表格, 测试中 68 | ::: 69 | 70 | ::: api-table src=components/PixelIt/types.ts 71 | ::: -------------------------------------------------------------------------------- /packages/docs/vitepress/demo/Tag/Effect.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 52 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/hooks/use-namespaces.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 钩子函数使用 3 | * const ns = useNameSpace(); 4 | * ns.b() => block 5 | * ns.e(element) => block__element 6 | * ns.m(modifier) => block--modifier 7 | * ns.bem(element,modifier) => block__element--modifier 8 | */ 9 | 10 | interface UseNameSpaceReturn { 11 | b: () => string 12 | e: (element: string) => string 13 | m: (modifier: string) => string 14 | bem: (_block?: string, element?: string, modifier?: string) => string 15 | } 16 | 17 | const defaultPrefix = 'vitepress-demo-preview' 18 | 19 | const generateName = (prefix: string, block?: string, element?: string, modifier?: string) => { 20 | let defaultName = block === '' ? `${prefix}` : `${prefix}-${block}` 21 | if (element) defaultName += `__${element}` 22 | if (modifier) defaultName += `--${modifier}` 23 | return defaultName 24 | } 25 | 26 | export const useNameSpace = (block: string = ''): UseNameSpaceReturn => { 27 | const b = () => generateName(defaultPrefix, block) 28 | const e = (element: string = '') => generateName(defaultPrefix, block, element) 29 | const m = (modifier: string = '') => generateName(defaultPrefix, block, '', modifier) 30 | const bem = (_block?: string, element?: string, modifier?: string) => 31 | generateName(defaultPrefix, _block, element, modifier) 32 | 33 | return { 34 | b, 35 | e, 36 | m, 37 | bem 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /libs/vitepress-preview-component/messages/message-notice.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 51 | 52 | 53 | --------------------------------------------------------------------------------