mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
Merge branch 'dev' into next
This commit is contained in:
commit
bcb7eabff3
@ -96,7 +96,7 @@ Vant 3 supports modern browsers and Chrome >= 51、iOS >= 10.0 (same as Vue 3).
|
||||
| Project | Description |
|
||||
| --- | --- |
|
||||
| [3lang3/react-vant](https://github.com/3lang3/react-vant) | React mobile UI Components based on Vant |
|
||||
| [mxdi9i7/vant-react](https://github.com/mxdi9i7/vant-react) | Mobile UI Components built on React and TS, inspired by Vant |
|
||||
| [rc-ui-lib](https://github.com/rancui/rc-ui-lib) | React mobile UI Components based on Vant |
|
||||
| [vant-aliapp](https://github.com/ant-move/Vant-Aliapp) | Alipay MiniProgram UI |
|
||||
| [taroify](https://gitee.com/mallfoundry/taroify) | Vant Taro |
|
||||
| [vant-theme](https://github.com/Aisen60/vant-theme) | Online theme preview built on Vant UI |
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
### 介绍
|
||||
|
||||
Vant 是**有赞前端团队**开源的移动端组件库,于 2017 年开源,已持续维护 4 年时间。Vant 对内承载了有赞所有核心业务,对外服务十多万开发者,是业界主流的移动端组件库之一。
|
||||
Vant 是**有赞前端团队**开源的移动端组件库,于 2017 年开源。Vant 对内承载了有赞所有核心业务,对外服务十多万开发者,是业界主流的移动端组件库之一。
|
||||
|
||||
目前 Vant 官方提供了 [Vue 2 版本](https://vant-contrib.gitee.io/vant)、[Vue 3 版本](https://vant-contrib.gitee.io/vant/v3)和[微信小程序版本](http://vant-contrib.gitee.io/vant-weapp),并由社区团队维护 [React 版本](https://github.com/mxdi9i7/vant-react)和[支付宝小程序版本](https://github.com/ant-move/Vant-Aliapp)。
|
||||
|
||||
@ -104,7 +104,7 @@ Vant 3 支持现代浏览器以及 Chrome >= 51、iOS >= 10.0(与 Vue 3 一致
|
||||
| 项目 | 描述 |
|
||||
| --- | --- |
|
||||
| [3lang3/react-vant](https://github.com/3lang3/react-vant) | 参照 Vant 打造的 React 框架移动端组件库 |
|
||||
| [mxdi9i7/vant-react](https://github.com/mxdi9i7/vant-react) | 基于 React 和 TS 构建的移动端组件库 |
|
||||
| [rc-ui-lib](https://github.com/rancui/rc-ui-lib) | 参照 Vant 打造的 React 框架移动端组件库 |
|
||||
| [vant-aliapp](https://github.com/ant-move/Vant-Aliapp) | Vant 支付宝小程序版 |
|
||||
| [taroify](https://gitee.com/mallfoundry/taroify) | Vant Taro 版 |
|
||||
| [vant-theme](https://github.com/Aisen60/vant-theme) | Vant 在线主题预览工具 |
|
||||
|
@ -31,7 +31,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vant/cli": "^3.9.0",
|
||||
"@vue/compiler-sfc": "^3.0.0",
|
||||
"vue": "^3.0.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
1
packages/vant-area-data/build.js
Normal file
1
packages/vant-area-data/build.js
Normal file
@ -0,0 +1 @@
|
||||
require('../vant-use/build');
|
@ -1,12 +1,17 @@
|
||||
{
|
||||
"name": "@vant/area-data",
|
||||
"version": "1.1.3",
|
||||
"version": "1.2.1",
|
||||
"description": "Vant 省市区数据",
|
||||
"main": "./lib/index.js",
|
||||
"typings": "./lib/index.d.ts",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "rimraf ./lib && tsc",
|
||||
"release": "pnpm build && npm publish",
|
||||
"clean": "rimraf ./dist",
|
||||
"dev": "node ./build.js -w",
|
||||
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
|
||||
"build:bundle": "node ./build.js",
|
||||
"build": "pnpm clean && pnpm build:bundle && pnpm build:types",
|
||||
"release": "pnpm build && release-it",
|
||||
"prepare": "pnpm build"
|
||||
},
|
||||
"publishConfig": {
|
||||
@ -20,5 +25,16 @@
|
||||
},
|
||||
"bugs": "https://github.com/youzan/vant/issues",
|
||||
"author": "chenjiahan",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.13.15",
|
||||
"release-it": "^14.2.2",
|
||||
"typescript": "~4.5.2"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"tag": false,
|
||||
"commitMessage": "release: @vant/area-data ${version}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ export const areaList = {
|
||||
711100: '新北市',
|
||||
711200: '宜兰县',
|
||||
711300: '新竹县',
|
||||
711400: '桃园县',
|
||||
711400: '桃园市',
|
||||
711500: '苗栗县',
|
||||
711700: '彰化县',
|
||||
711900: '嘉义县',
|
||||
@ -1290,8 +1290,8 @@ export const areaList = {
|
||||
330110: '余杭区',
|
||||
330111: '富阳区',
|
||||
330112: '临安区',
|
||||
330113: '钱塘区',
|
||||
330114: '临平区',
|
||||
330113: '临平区',
|
||||
330114: '钱塘区',
|
||||
330122: '桐庐县',
|
||||
330127: '淳安县',
|
||||
330182: '建德市',
|
||||
|
@ -1,8 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"target": "ES2019",
|
||||
"outDir": "./lib",
|
||||
"outDir": "./dist",
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
|
@ -1,30 +0,0 @@
|
||||
module.exports = function (api, options) {
|
||||
if (api) {
|
||||
api.cache.never();
|
||||
}
|
||||
|
||||
const { BABEL_MODULE, NODE_ENV } = process.env;
|
||||
const isTest = NODE_ENV === 'test';
|
||||
const useESModules = BABEL_MODULE !== 'commonjs' && !isTest;
|
||||
|
||||
return {
|
||||
presets: [
|
||||
[
|
||||
require.resolve('@babel/preset-env'),
|
||||
{
|
||||
modules: useESModules ? false : 'commonjs',
|
||||
loose: options.loose,
|
||||
},
|
||||
],
|
||||
require.resolve('@babel/preset-typescript'),
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
require.resolve('@vue/babel-plugin-jsx'),
|
||||
{
|
||||
enableObjectSlots: options.enableObjectSlots,
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
};
|
@ -16,8 +16,7 @@ const DEFAULT_CONFIG = {
|
||||
setupFilesAfterEnv: [JEST_SETUP_FILE],
|
||||
moduleFileExtensions: ['js', 'jsx', 'vue', 'ts', 'tsx'],
|
||||
transform: {
|
||||
'\\.(vue)$': 'vue3-jest',
|
||||
'\\.(js|jsx|ts|tsx)$': 'babel-jest',
|
||||
'\\.(js|jsx|ts|tsx|vue)$': '<rootDir>/node_modules/@vant/cli/cjs/jest.transformer.cjs',
|
||||
},
|
||||
transformIgnorePatterns: ['/node_modules/(?!(@vant/cli))/'],
|
||||
snapshotSerializers: ['jest-serializer-html'],
|
||||
|
92
packages/vant-cli/cjs/jest.transformer.cjs
Normal file
92
packages/vant-cli/cjs/jest.transformer.cjs
Normal file
@ -0,0 +1,92 @@
|
||||
const sfc = require('vue/compiler-sfc');
|
||||
const babel = require('@babel/core');
|
||||
const esbuild = require('esbuild');
|
||||
const nodePath = require('path');
|
||||
|
||||
const isJsxFile = (path) => /\.(j|t)sx$/.test(path);
|
||||
const isTsxFile = (path) => /\.tsx$/.test(path);
|
||||
const isVueFile = (path) => /\.vue$/.test(path);
|
||||
|
||||
const transformJsx = (code, path) => {
|
||||
const babelResult = babel.transformSync(code, {
|
||||
filename: path,
|
||||
babelrc: false,
|
||||
presets: isTsxFile(path) ? ['@babel/preset-typescript'] : [],
|
||||
plugins: [['@vue/babel-plugin-jsx']],
|
||||
});
|
||||
return babelResult?.code || '';
|
||||
};
|
||||
|
||||
const transformSFC = (code, path) => {
|
||||
const parsedPath = nodePath.parse(path);
|
||||
const { descriptor, errors } = sfc.parse(code, {
|
||||
filename: parsedPath.base,
|
||||
sourceRoot: parsedPath.dir,
|
||||
});
|
||||
|
||||
if (errors.length) {
|
||||
errors.forEach((error) => console.error(error));
|
||||
return '';
|
||||
}
|
||||
|
||||
const output = [];
|
||||
let bindingMetadata = {};
|
||||
|
||||
if (descriptor.script) {
|
||||
const content = descriptor.script.content.replace(
|
||||
'export default',
|
||||
'const script ='
|
||||
);
|
||||
output.push(content);
|
||||
} else if (descriptor.scriptSetup) {
|
||||
const result = sfc.compileScript(descriptor, {
|
||||
id: 'mock',
|
||||
});
|
||||
|
||||
const content = result.content.replace('export default', 'const script =');
|
||||
output.push(content);
|
||||
|
||||
if (result.bindings) {
|
||||
bindingMetadata = result.bindings;
|
||||
}
|
||||
} else {
|
||||
output.push(`const script = {};`);
|
||||
}
|
||||
|
||||
if (descriptor.template) {
|
||||
const render = sfc.compileTemplate({
|
||||
id: 'mock',
|
||||
source: descriptor.template.content,
|
||||
filename: path,
|
||||
compilerOptions: {
|
||||
bindingMetadata,
|
||||
},
|
||||
}).code;
|
||||
output.push(render);
|
||||
output.push('script.render = render;');
|
||||
}
|
||||
|
||||
output.push('export default script;');
|
||||
|
||||
return output.join('\n');
|
||||
};
|
||||
|
||||
const transformScript = (code) =>
|
||||
esbuild.transformSync(code, {
|
||||
target: 'es2016',
|
||||
format: 'cjs',
|
||||
loader: 'ts',
|
||||
}).code;
|
||||
|
||||
module.exports = {
|
||||
canInstrument: true,
|
||||
process(code, path) {
|
||||
if (isVueFile(path)) {
|
||||
code = transformSFC(code, path);
|
||||
}
|
||||
if (isJsxFile(path)) {
|
||||
code = transformJsx(code, path);
|
||||
}
|
||||
return transformScript(code);
|
||||
},
|
||||
};
|
@ -21,8 +21,6 @@
|
||||
- [site.simulator.url](#sitesimulatorurl)
|
||||
- [site.htmlMeta](#sitehtmlmeta)
|
||||
- [site.enableVConsole](#siteenablevconsole)
|
||||
- [Babel](#babel)
|
||||
- [默认配置](#----)
|
||||
- [Postcss](#postcss)
|
||||
- [默认配置](#-----1)
|
||||
- [browserslist](#browserslist)
|
||||
@ -337,36 +335,13 @@ module.exports = {
|
||||
|
||||
是否在 dev 时开启 [vConsole](https://github.com/Tencent/vConsole) 调试,用于移动端 debug。
|
||||
|
||||
## Babel
|
||||
|
||||
通过根目录下的`babel.config.js`文件可以对 Babel 进行配置。
|
||||
|
||||
### 默认配置
|
||||
|
||||
推荐使用`vant-cli`内置的 preset,配置如下:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
presets: ['@vant/cli/preset'],
|
||||
};
|
||||
```
|
||||
|
||||
`@vant/cli/preset`中默认包含了以下插件:
|
||||
|
||||
- @babel/preset-env(不含 core-js)
|
||||
- @babel/preset-typescript
|
||||
- @babel/plugin-transform-object-assign
|
||||
- @babel/plugin-proposal-optional-chaining
|
||||
- @babel/plugin-proposal-nullish-coalescing-operator
|
||||
- @vue/babel-preset-jsx
|
||||
|
||||
## Postcss
|
||||
|
||||
通过根目录下的`postcss.config.js`文件可以对 Postcss 进行配置。
|
||||
|
||||
### 默认配置
|
||||
|
||||
`vant-cli`中默认的 Postcss 配置如下:
|
||||
`vant-cli` 中默认的 Postcss 配置如下:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
@ -378,7 +353,7 @@ module.exports = {
|
||||
|
||||
## browserslist
|
||||
|
||||
推荐在`package.json`文件里添加 browserslist 字段,这个值会被`@babel/preset-env`和`autoprefixer`用来确定目标浏览器的版本,保证编译后代码的兼容性。
|
||||
推荐在 `package.json` 文件里添加 browserslist 字段,这个值会被 `autoprefixer` 用来确定目标浏览器的版本,保证编译后代码的兼容性。
|
||||
|
||||
在移动端浏览器中使用,可以添加如下配置:
|
||||
|
||||
|
@ -14,7 +14,6 @@ project
|
||||
│ ├─ home.md # 文档首页
|
||||
│ └─ changelog.md # 更新日志
|
||||
│
|
||||
├─ babel.config.js # Babel 配置文件
|
||||
├─ vant.config.mjs # Vant Cli 配置文件
|
||||
├─ package.json
|
||||
└─ README.md
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vant/cli",
|
||||
"version": "4.0.0-rc.4",
|
||||
"version": "4.0.0-rc.5",
|
||||
"type": "module",
|
||||
"main": "lib/index.js",
|
||||
"typings": "lib/index.d.ts",
|
||||
@ -21,8 +21,7 @@
|
||||
"cjs",
|
||||
"site",
|
||||
"template",
|
||||
"bin.js",
|
||||
"preset.cjs"
|
||||
"bin.js"
|
||||
],
|
||||
"keywords": [
|
||||
"vant"
|
||||
@ -42,32 +41,28 @@
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/less": "^3.0.3",
|
||||
"@types/lodash-es": "^4.17.5",
|
||||
"@types/markdown-it": "^12.2.3",
|
||||
"@vue/compiler-sfc": "^3.2.20",
|
||||
"vue": "^3.2.20"
|
||||
"vue": "^3.2.27"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/jest": "^27.0.3",
|
||||
"@babel/core": "^7.16.0",
|
||||
"@babel/preset-env": "^7.16.0",
|
||||
"@babel/preset-typescript": "^7.16.0",
|
||||
"@docsearch/css": "3.0.0-alpha.41",
|
||||
"@docsearch/js": "3.0.0-alpha.41",
|
||||
"@types/jest": "^27.0.3",
|
||||
"@vant/eslint-config": "^3.3.2",
|
||||
"@vant/markdown-vetur": "^2.2.0",
|
||||
"@vant/stylelint-config": "^1.4.2",
|
||||
"@vant/touch-emulator": "^1.3.2",
|
||||
"@vitejs/plugin-vue": "^1.9.4",
|
||||
"@vitejs/plugin-vue-jsx": "^1.2.0",
|
||||
"@vitejs/plugin-vue": "^2.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^1.3.3",
|
||||
"@vue/babel-plugin-jsx": "^1.1.1",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"babel-jest": "^27.3.1",
|
||||
"chalk": "^4.1.2",
|
||||
"clean-css": "^5.2.2",
|
||||
"commander": "^8.3.0",
|
||||
"consola": "^2.15.3",
|
||||
"conventional-changelog": "^3.1.24",
|
||||
"esbuild": "^0.14.2",
|
||||
"eslint": "^8.1.0",
|
||||
"execa": "^5.1.1",
|
||||
"fast-glob": "^3.2.7",
|
||||
@ -81,7 +76,6 @@
|
||||
"jest-serializer-html": "^7.1.0",
|
||||
"less": "^4.1.2",
|
||||
"lint-staged": "^12.1.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"markdown-it": "^12.2.0",
|
||||
"markdown-it-anchor": "^8.4.1",
|
||||
"ora": "^6.0.1",
|
||||
@ -91,13 +85,11 @@
|
||||
"release-it": "^14.11.6",
|
||||
"stylelint": "^13.0.0",
|
||||
"transliteration": "^2.2.0",
|
||||
"ts-jest": "^27.0.7",
|
||||
"typescript": "^4.5.2",
|
||||
"vite": "^2.6.13",
|
||||
"vite": "^2.7.10",
|
||||
"vite-plugin-html": "^2.1.1",
|
||||
"vite-plugin-md": "^0.11.4",
|
||||
"vue-router": "^4.0.12",
|
||||
"vue3-jest": "^27.0.0-alpha.2"
|
||||
"vue-router": "^4.0.12"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
|
@ -1,3 +0,0 @@
|
||||
const babelConfig = require('./cjs/babel.config.cjs');
|
||||
|
||||
module.exports = (api, options) => babelConfig(api, options);
|
@ -21,7 +21,7 @@ pre {
|
||||
margin: 20px 0 0;
|
||||
|
||||
+ p {
|
||||
margin-top: 20px;
|
||||
margin-top: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title><%= title %></title>
|
||||
<% if (description) { %>
|
||||
<meta name="description" content="<%= description %>" />
|
||||
<% } %>
|
||||
<link rel="icon" type="image/png" href="<%= logo %>" />
|
||||
<meta
|
||||
name="viewport"
|
||||
|
@ -3,7 +3,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title><%- title %></title>
|
||||
<% if (description) { %>
|
||||
<meta name="description" content="<%- description %>" />
|
||||
<% } %>
|
||||
<link rel="icon" type="image/png" href="<%- logo %>" />
|
||||
<meta
|
||||
name="viewport"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import fse from 'fs-extra';
|
||||
import execa from 'execa';
|
||||
import { join, relative } from 'path';
|
||||
import fse from 'fs-extra';
|
||||
import { clean } from './clean.js';
|
||||
import { CSS_LANG } from '../common/css.js';
|
||||
import { ora, consola } from '../common/logger.js';
|
||||
@ -27,12 +27,13 @@ import {
|
||||
setModuleEnv,
|
||||
setBuildTarget,
|
||||
} from '../common/index.js';
|
||||
import type { Format } from 'esbuild';
|
||||
|
||||
const { remove, copy, readdir, existsSync } = fse;
|
||||
|
||||
async function compileFile(filePath: string) {
|
||||
async function compileFile(filePath: string, format: Format) {
|
||||
if (isScript(filePath)) {
|
||||
return compileScript(filePath);
|
||||
return compileScript(filePath, format);
|
||||
}
|
||||
if (isStyle(filePath)) {
|
||||
return compileStyle(filePath);
|
||||
@ -69,12 +70,14 @@ async function preCompileDir(dir: string) {
|
||||
);
|
||||
}
|
||||
|
||||
async function compileDir(dir: string) {
|
||||
async function compileDir(dir: string, format: Format) {
|
||||
const files = await readdir(dir);
|
||||
await Promise.all(
|
||||
files.map((filename) => {
|
||||
const filePath = join(dir, filename);
|
||||
return isDir(filePath) ? compileDir(filePath) : compileFile(filePath);
|
||||
return isDir(filePath)
|
||||
? compileDir(filePath, format)
|
||||
: compileFile(filePath, format);
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -86,13 +89,13 @@ async function copySourceCode() {
|
||||
async function buildESMOutputs() {
|
||||
setModuleEnv('esmodule');
|
||||
setBuildTarget('package');
|
||||
await compileDir(ES_DIR);
|
||||
await compileDir(ES_DIR, 'esm');
|
||||
}
|
||||
|
||||
async function buildCJSOutputs() {
|
||||
setModuleEnv('commonjs');
|
||||
setBuildTarget('package');
|
||||
await compileDir(LIB_DIR);
|
||||
await compileDir(LIB_DIR, 'cjs');
|
||||
}
|
||||
|
||||
async function buildTypeDeclarations() {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { get } from 'lodash-es';
|
||||
import { existsSync, readFileSync } from 'fs';
|
||||
import { fileURLToPath, pathToFileURL } from 'url';
|
||||
import { join, dirname, isAbsolute } from 'path';
|
||||
@ -74,7 +73,7 @@ export function getVantConfig() {
|
||||
|
||||
function getSrcDir() {
|
||||
const vantConfig = getVantConfig();
|
||||
const srcDir = get(vantConfig, 'build.srcDir');
|
||||
const srcDir = vantConfig.build?.srcDir;
|
||||
|
||||
if (srcDir) {
|
||||
if (isAbsolute(srcDir)) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { get } from 'lodash-es';
|
||||
import { existsSync } from 'fs';
|
||||
import { join, isAbsolute } from 'path';
|
||||
import { getVantConfig } from '../common/index.js';
|
||||
@ -8,7 +7,7 @@ type CSS_LANG = 'css' | 'less' | 'scss';
|
||||
|
||||
function getCssLang(): CSS_LANG {
|
||||
const vantConfig = getVantConfig();
|
||||
const preprocessor = get(vantConfig, 'build.css.preprocessor', 'less');
|
||||
const preprocessor = vantConfig.build?.css?.preprocessor || 'less';
|
||||
|
||||
if (preprocessor === 'sass') {
|
||||
return 'scss';
|
||||
@ -23,7 +22,7 @@ export function getCssBaseFile() {
|
||||
const vantConfig = getVantConfig();
|
||||
let path = join(STYLE_DIR, `base.${CSS_LANG}`);
|
||||
|
||||
const baseFile = get(vantConfig, 'build.css.base', '');
|
||||
const baseFile = vantConfig.build?.css?.base || '';
|
||||
if (baseFile) {
|
||||
path = isAbsolute(baseFile) ? baseFile : join(SRC_DIR, baseFile);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import fse from 'fs-extra';
|
||||
import { get } from 'lodash-es';
|
||||
import { sep, join } from 'path';
|
||||
import { SRC_DIR, getVantConfig } from './constant.js';
|
||||
import type { InlineConfig } from 'vite';
|
||||
@ -14,6 +13,7 @@ export const TEST_REGEXP = new RegExp('\\' + sep + 'test$');
|
||||
export const ASSET_REGEXP = /\.(png|jpe?g|gif|webp|ico|jfif|svg|woff2?|ttf)$/i;
|
||||
export const STYLE_REGEXP = /\.(css|less|scss)$/;
|
||||
export const SCRIPT_REGEXP = /\.(js|ts|jsx|tsx)$/;
|
||||
export const JSX_REGEXP = /\.(j|t)sx$/;
|
||||
export const ENTRY_EXTS = ['js', 'ts', 'tsx', 'jsx', 'vue'];
|
||||
|
||||
export function removeExt(path: string) {
|
||||
@ -46,33 +46,14 @@ export function getComponents() {
|
||||
);
|
||||
}
|
||||
|
||||
export function isDir(dir: string) {
|
||||
return lstatSync(dir).isDirectory();
|
||||
}
|
||||
|
||||
export function isDemoDir(dir: string) {
|
||||
return DEMO_REGEXP.test(dir);
|
||||
}
|
||||
|
||||
export function isTestDir(dir: string) {
|
||||
return TEST_REGEXP.test(dir);
|
||||
}
|
||||
|
||||
export function isAsset(path: string) {
|
||||
return ASSET_REGEXP.test(path);
|
||||
}
|
||||
|
||||
export function isSfc(path: string) {
|
||||
return SFC_REGEXP.test(path);
|
||||
}
|
||||
|
||||
export function isStyle(path: string) {
|
||||
return STYLE_REGEXP.test(path);
|
||||
}
|
||||
|
||||
export function isScript(path: string) {
|
||||
return SCRIPT_REGEXP.test(path);
|
||||
}
|
||||
export const isDir = (dir: string) => lstatSync(dir).isDirectory();
|
||||
export const isDemoDir = (dir: string) => DEMO_REGEXP.test(dir);
|
||||
export const isTestDir = (dir: string) => TEST_REGEXP.test(dir);
|
||||
export const isAsset = (path: string) => ASSET_REGEXP.test(path);
|
||||
export const isSfc = (path: string) => SFC_REGEXP.test(path);
|
||||
export const isStyle = (path: string) => STYLE_REGEXP.test(path);
|
||||
export const isScript = (path: string) => SCRIPT_REGEXP.test(path);
|
||||
export const isJsx = (path: string) => JSX_REGEXP.test(path);
|
||||
|
||||
const camelizeRE = /-(\w)/g;
|
||||
const pascalizeRE = /(\w)(\w*)/g;
|
||||
@ -135,7 +116,7 @@ export function smartOutputFile(filePath: string, content: string) {
|
||||
|
||||
export function mergeCustomViteConfig(config: InlineConfig) {
|
||||
const vantConfig = getVantConfig();
|
||||
const configureVite = get(vantConfig, 'build.configureVite');
|
||||
const configureVite = vantConfig.build?.configureVite;
|
||||
|
||||
if (configureVite) {
|
||||
return configureVite(config);
|
||||
|
@ -1,15 +1,17 @@
|
||||
import postcss from 'postcss';
|
||||
import postcssrc from 'postcss-load-config';
|
||||
import CleanCss from 'clean-css';
|
||||
import { transform } from 'esbuild';
|
||||
import { POSTCSS_CONFIG_FILE } from '../common/constant.js';
|
||||
|
||||
const cleanCss = new CleanCss();
|
||||
|
||||
export async function compileCss(source: string | Buffer) {
|
||||
const config = await postcssrc({}, POSTCSS_CONFIG_FILE);
|
||||
const { css } = await postcss(config.plugins as any).process(source, {
|
||||
from: undefined,
|
||||
});
|
||||
|
||||
return cleanCss.minify(css).styles;
|
||||
const result = await transform(css, {
|
||||
loader: 'css',
|
||||
minify: true,
|
||||
target: ['chrome53', 'safari10'],
|
||||
});
|
||||
return result.code;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { createRequire } from 'module';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
// allow to import from node_modules
|
||||
// @import "~package-name/var.scss"
|
||||
const tildeImporter = (url: string) => {
|
||||
@ -16,7 +18,6 @@ const tildeImporter = (url: string) => {
|
||||
};
|
||||
|
||||
export async function compileSass(filePath: string) {
|
||||
const require = createRequire(import.meta.url);
|
||||
const { renderSync } = require('sass');
|
||||
const { css } = renderSync({ file: filePath, importer: tildeImporter });
|
||||
return css;
|
||||
|
@ -1,36 +1,56 @@
|
||||
import fse from 'fs-extra';
|
||||
import babel from '@babel/core';
|
||||
import esbuild, { type Format } from 'esbuild';
|
||||
import { sep } from 'path';
|
||||
import { transformAsync } from '@babel/core';
|
||||
import { replaceExt } from '../common/index.js';
|
||||
import { isJsx, replaceExt } from '../common/index.js';
|
||||
import { replaceCSSImportExt } from '../common/css.js';
|
||||
import { replaceScriptImportExt } from './get-deps.js';
|
||||
|
||||
const { readFileSync, removeSync, outputFileSync } = fse;
|
||||
|
||||
export async function compileScript(filePath: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (filePath.includes('.d.ts')) {
|
||||
resolve();
|
||||
return;
|
||||
export async function compileScript(
|
||||
filePath: string,
|
||||
format: Format
|
||||
): Promise<void> {
|
||||
if (filePath.includes('.d.ts')) {
|
||||
return;
|
||||
}
|
||||
|
||||
let code = readFileSync(filePath, 'utf-8');
|
||||
|
||||
if (!filePath.includes(`${sep}style${sep}`)) {
|
||||
code = replaceCSSImportExt(code);
|
||||
}
|
||||
code = replaceScriptImportExt(code, '.vue', '');
|
||||
|
||||
if (isJsx(filePath)) {
|
||||
const babelResult = await babel.transformAsync(code, {
|
||||
filename: filePath,
|
||||
babelrc: false,
|
||||
presets: ['@babel/preset-typescript'],
|
||||
plugins: [
|
||||
[
|
||||
'@vue/babel-plugin-jsx',
|
||||
{
|
||||
enableObjectSlots: false,
|
||||
},
|
||||
],
|
||||
],
|
||||
});
|
||||
if (babelResult?.code) {
|
||||
({ code } = babelResult);
|
||||
}
|
||||
}
|
||||
|
||||
let code = readFileSync(filePath, 'utf-8');
|
||||
|
||||
if (!filePath.includes(`${sep}style${sep}`)) {
|
||||
code = replaceCSSImportExt(code);
|
||||
}
|
||||
code = replaceScriptImportExt(code, '.vue', '');
|
||||
|
||||
transformAsync(code, { filename: filePath })
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
const jsFilePath = replaceExt(filePath, '.js');
|
||||
|
||||
removeSync(filePath);
|
||||
outputFileSync(jsFilePath, result.code);
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
.catch(reject);
|
||||
const esbuildResult = await esbuild.transform(code, {
|
||||
loader: 'ts',
|
||||
target: 'es2016',
|
||||
format,
|
||||
});
|
||||
|
||||
({ code } = esbuildResult);
|
||||
|
||||
const jsFilePath = replaceExt(filePath, '.js');
|
||||
removeSync(filePath);
|
||||
outputFileSync(jsFilePath, code);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import fse from 'fs-extra';
|
||||
import path from 'path';
|
||||
import hash from 'hash-sum';
|
||||
import { parse, SFCBlock, compileTemplate } from '@vue/compiler-sfc';
|
||||
import { parse, SFCBlock, compileTemplate } from 'vue/compiler-sfc';
|
||||
import { replaceExt } from '../common/index.js';
|
||||
|
||||
const { remove, readFileSync, outputFile } = fse;
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { get } from 'lodash-es';
|
||||
import { join } from 'path';
|
||||
import {
|
||||
pascalize,
|
||||
@ -72,8 +71,8 @@ export function genPackageEntry({
|
||||
const names = getComponents();
|
||||
const vantConfig = getVantConfig();
|
||||
|
||||
const namedExport = get(vantConfig, 'build.namedExport', false);
|
||||
const skipInstall = get(vantConfig, 'build.skipInstall', []).map(pascalize);
|
||||
const namedExport = vantConfig.build?.namedExport || false;
|
||||
const skipInstall = (vantConfig.build?.skipInstall || []).map(pascalize);
|
||||
|
||||
const version = process.env.PACKAGE_VERSION || getPackageJson().version;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import markdownVetur from '@vant/markdown-vetur';
|
||||
import { get } from 'lodash-es';
|
||||
import {
|
||||
SRC_DIR,
|
||||
VETUR_DIR,
|
||||
@ -11,13 +10,13 @@ import {
|
||||
export function genVeturConfig() {
|
||||
const pkgJson = getPackageJson();
|
||||
const vantConfig = getVantConfig();
|
||||
const options = get(vantConfig, 'build.vetur');
|
||||
const options = vantConfig.build?.vetur;
|
||||
|
||||
if (options) {
|
||||
markdownVetur.parseAndWrite({
|
||||
name: vantConfig.name,
|
||||
path: SRC_DIR,
|
||||
test: /zh-CN\.md/,
|
||||
test: /README\.md/,
|
||||
version: pkgJson.version,
|
||||
outputDir: VETUR_DIR,
|
||||
...options,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { join } from 'path';
|
||||
import { get } from 'lodash-es';
|
||||
import { createRequire } from 'module';
|
||||
import hljs from 'highlight.js';
|
||||
import vitePluginMd from 'vite-plugin-md';
|
||||
@ -82,7 +81,7 @@ function getTitle(config: { title: string; description?: string }) {
|
||||
}
|
||||
|
||||
function getHTMLMeta(vantConfig: any) {
|
||||
const meta = get(vantConfig, 'site.htmlMeta');
|
||||
const meta = vantConfig.site?.htmlMeta;
|
||||
|
||||
if (meta) {
|
||||
return Object.keys(meta)
|
||||
@ -99,8 +98,8 @@ export function getViteConfigForSiteDev(): InlineConfig {
|
||||
const vantConfig = getVantConfig();
|
||||
const siteConfig = getSiteConfig(vantConfig);
|
||||
const title = getTitle(siteConfig);
|
||||
const baiduAnalytics = get(vantConfig, 'site.baiduAnalytics');
|
||||
const enableVConsole = isDev() && get(vantConfig, 'site.enableVConsole');
|
||||
const baiduAnalytics = vantConfig.site?.baiduAnalytics;
|
||||
const enableVConsole = isDev() && vantConfig.site?.enableVConsole;
|
||||
|
||||
return {
|
||||
root: SITE_SRC_DIR,
|
||||
@ -136,6 +135,9 @@ export function getViteConfigForSiteDev(): InlineConfig {
|
||||
data: {
|
||||
...siteConfig,
|
||||
title,
|
||||
// `description` is used by the HTML ejs template,
|
||||
// so it needs to be written explicitly here to avoid error: description is not defined
|
||||
description: siteConfig.description,
|
||||
baiduAnalytics,
|
||||
enableVConsole,
|
||||
meta: getHTMLMeta(vantConfig),
|
||||
@ -159,8 +161,8 @@ export function getViteConfigForSiteDev(): InlineConfig {
|
||||
export function getViteConfigForSiteProd(): InlineConfig {
|
||||
const devConfig = getViteConfigForSiteDev();
|
||||
const vantConfig = getVantConfig();
|
||||
const outDir = get(vantConfig, 'build.site.outputDir', SITE_DIST_DIR);
|
||||
const publicPath = get(vantConfig, 'build.site.publicPath', '/');
|
||||
const outDir = vantConfig.build?.site?.outputDir || SITE_DIST_DIR;
|
||||
const publicPath = vantConfig.build?.site?.publicPath || '/';
|
||||
|
||||
return {
|
||||
...devConfig,
|
||||
|
1
packages/vant-cli/src/module.d.ts
vendored
1
packages/vant-cli/src/module.d.ts
vendored
@ -1,7 +1,6 @@
|
||||
// some modules with missing type definitions
|
||||
declare module 'execa';
|
||||
declare module 'hash-sum';
|
||||
declare module 'clean-css';
|
||||
declare module 'release-it';
|
||||
declare module 'conventional-changelog';
|
||||
declare module '@vant/markdown-vetur';
|
||||
|
@ -1,5 +1,13 @@
|
||||
## Changelog
|
||||
|
||||
## 1.7.3
|
||||
|
||||
- complete https protocol
|
||||
|
||||
## 1.7.2
|
||||
|
||||
- add cash-o icon
|
||||
|
||||
## 1.7.1
|
||||
|
||||
- add guide-o icon
|
||||
|
@ -17,16 +17,3 @@ pnpm add @vant/icons
|
||||
|
||||
- [Usage in Vue](https://youzan.github.io/vant/#/zh-CN/icon)
|
||||
- [Usage in Weapp](https://youzan.github.io/vant-weapp/#/icon)
|
||||
|
||||
## Contribution
|
||||
|
||||
### Update Icons
|
||||
|
||||
1. Update assets/icons.sketch
|
||||
2. Make a Pull Request
|
||||
|
||||
### Add New Icon
|
||||
|
||||
1. Add new icon to assets/icons.sketch
|
||||
2. Add icon name to src/config.js
|
||||
3. Make a Pull Request
|
||||
|
Binary file not shown.
47
packages/vant-icons/contribution.zh-CN.md
Normal file
47
packages/vant-icons/contribution.zh-CN.md
Normal file
@ -0,0 +1,47 @@
|
||||
# 图标贡献指南
|
||||
|
||||
## 设计稿
|
||||
|
||||
Vant 图标库托管在 [iconfont.cn](https://iconfont.cn) 上,同时仓库中保留了一份完整的 Sketch 设计稿。
|
||||
|
||||
[在线预览链接](https://iconfont.cn/collections/detail?cid=31945)
|
||||
|
||||
## 更新流程
|
||||
|
||||
新增/更新图标的标准流程如下:
|
||||
|
||||
### 1. 绘制图标
|
||||
|
||||
在 Sketch 中绘制所需的图标,并更新到 `assets/icons.sketch` 文件中。
|
||||
|
||||
绘制图标前,请阅读:[iconfont - 图标绘制](https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.16&helptype=draw)。
|
||||
|
||||
### 2. 上传图标
|
||||
|
||||
从 Sketch 中导出图标对应的 SVG 文件,并上传到 [iconfont 项目](https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=2553510)中。
|
||||
|
||||
<img src="https://img.yzcdn.cn/upload_files/2021/12/21/Fi0XXEorB1SVr_BT-Dz6txHOKNlB.png" style="width: 800px;">
|
||||
|
||||
> 此步骤需要图标库管理员权限,请联系 Vant 维护者进行添加。
|
||||
|
||||
### 3. 更新代码
|
||||
|
||||
在 iconfont 中将更新后的图标库下载到本地,并更新以下文件:
|
||||
|
||||
- `src/index.less`: 更新字体文件的 CDN 链接。
|
||||
- `src/encode-woff2.less`: 更新字体文件的 base64 URL。
|
||||
|
||||
如果有新增图标,还需要更新以下文件:
|
||||
|
||||
- `src/config.js`: 增加新图标的英文名称。
|
||||
- `src/common.less`: 增加新图标的样式类。
|
||||
|
||||
字体文件的 base64 URL 通过 [transfonter](https://transfonter.org/) 生成,步骤如下图所示:
|
||||
|
||||
<img src="https://img01.yzcdn.cn/upload_files/2021/12/21/FlMHanQNhDV1XWaw8spnAtHKumjW.png" style="width: 800px;">
|
||||
|
||||
### 4. 发布图标库
|
||||
|
||||
执行 `yarn release` 命令,发布 `@vant/icons` 到 npm。
|
||||
|
||||
发布完成后,在对应仓库中进行升级,即可使用新图标。
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vant/icons",
|
||||
"version": "1.7.1",
|
||||
"version": "1.7.3",
|
||||
"description": "vant icons",
|
||||
"main": "./src/config.js",
|
||||
"types": "./src/config.d.ts",
|
||||
|
@ -973,3 +973,7 @@
|
||||
.van-icon-guide-o:before {
|
||||
content: '\e74c';
|
||||
}
|
||||
|
||||
.van-icon-cash-o:before {
|
||||
content: '\e74d';
|
||||
}
|
||||
|
@ -149,6 +149,7 @@ export default {
|
||||
'shrink',
|
||||
'shield-o',
|
||||
'guide-o',
|
||||
'cash-o',
|
||||
],
|
||||
filled: [
|
||||
// has corresponding outline icon
|
||||
|
File diff suppressed because one or more lines are too long
@ -5,10 +5,10 @@
|
||||
font-style: normal;
|
||||
font-display: auto;
|
||||
font-family: 'vant-icon';
|
||||
src: url('//at.alicdn.com/t/font_2553510_61agzg96wm8.woff2?t=1631948257467')
|
||||
src: url('https://at.alicdn.com/t/font_2553510_5imfhdc20ag.woff2?t=1640074908811')
|
||||
format('woff2'),
|
||||
url('//at.alicdn.com/t/font_2553510_61agzg96wm8.woff?t=1631948257467')
|
||||
url('https://at.alicdn.com/t/font_2553510_5imfhdc20ag.woff?t=1640074908811')
|
||||
format('woff'),
|
||||
url('//at.alicdn.com/t/font_2553510_61agzg96wm8.ttf?t=1631948257467')
|
||||
url('https://at.alicdn.com/t/font_2553510_5imfhdc20ag.ttf?t=1640074908811')
|
||||
format('truetype');
|
||||
}
|
||||
|
1964
packages/vant-icons/yarn.lock
Normal file
1964
packages/vant-icons/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
||||
# vant-markdown-loader
|
||||
|
||||
Simple and fast vue markdown loader, transform markdown to vue component.
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
# with npm
|
||||
npm i @vant/markdown-loader -D
|
||||
|
||||
# with yarn
|
||||
yarn add @vant/markdown-loader -D
|
||||
|
||||
# with pnpm
|
||||
pnpm add @vant/markdown-loader -D
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
- `enableMetaData`: Default `false`. Whether to use [front-matter](https://github.com/jxson/front-matter) to extract markdown meta data
|
||||
|
||||
- `linkOpen`: Default `true`. Whether to add target="\_blank" to all links
|
||||
|
||||
- `wrapper(html, fm)`: Format the returned content using a custom function
|
||||
- `html`: The result of [markdown-it](https://github.com/markdown-it/markdown-it)'s render
|
||||
- `fm`: See [fm(string)](https://github.com/jxson/front-matter#fmstring). If `enableMetaData` option is `false`, the value is `undefined`.
|
||||
- `attributes`
|
||||
- `body`
|
||||
- `frontmatter`
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "@vant/markdown-loader",
|
||||
"version": "4.1.1",
|
||||
"description": "Simple and fast vue markdown loader",
|
||||
"main": "src/index.js",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org/"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/youzan/vant.git",
|
||||
"directory": "packages/vant-markdown-loader"
|
||||
},
|
||||
"bugs": "https://github.com/youzan/vant/issues",
|
||||
"author": "chenjiahan",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"front-matter": "^4.0.2",
|
||||
"highlight.js": "^10.7.1",
|
||||
"loader-utils": "^2.0.0",
|
||||
"markdown-it": "^12.0.4",
|
||||
"markdown-it-anchor": "^8.0.0",
|
||||
"transliteration": "^2.2.0"
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
module.exports = function cardWrapper(html) {
|
||||
const group = html
|
||||
.replace(/<h3/g, ':::<h3')
|
||||
.replace(/<h2/g, ':::<h2')
|
||||
.split(':::');
|
||||
|
||||
return group
|
||||
.map(fragment => {
|
||||
if (fragment.indexOf('<h3') !== -1) {
|
||||
return `<div class="card">${fragment}</div>`;
|
||||
}
|
||||
|
||||
return fragment;
|
||||
})
|
||||
.join('');
|
||||
};
|
@ -1,42 +0,0 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const parser = require('./md-parser');
|
||||
|
||||
function hyphenate(str) {
|
||||
return str.replace(/\B([A-Z])/g, '-$1').toLowerCase();
|
||||
}
|
||||
|
||||
module.exports = function extraDemo(content) {
|
||||
const isWin = /^win/.test(os.platform());
|
||||
const markdownDir = path.dirname(this.resourcePath);
|
||||
const demoLinks = [];
|
||||
|
||||
content = content.replace(
|
||||
/<demo-code([\s\S]*?)>([\s\S]*?)<\/demo-code>/g,
|
||||
function (_, attrs, link) {
|
||||
link = link.trim(); // 去换行符
|
||||
const tag = 'demo-code-' + hyphenate(path.basename(link, '.vue'));
|
||||
let fullLink;
|
||||
if (isWin) {
|
||||
fullLink = path.posix.join(...markdownDir.split(path.sep), link);
|
||||
} else {
|
||||
fullLink = path.join(markdownDir, link);
|
||||
}
|
||||
demoLinks.indexOf(fullLink) === -1 && demoLinks.push(fullLink);
|
||||
const demoContent = fs.readFileSync(fullLink, { encoding: 'utf8' });
|
||||
const demoParseredContent = parser.render(
|
||||
'```html\n' + demoContent + '\n```'
|
||||
);
|
||||
return `
|
||||
<demo-playground${attrs}
|
||||
origin-code="${escape(demoContent)}"
|
||||
code-snippet="${escape(demoParseredContent)}">
|
||||
<${tag} />
|
||||
</demo-playground>
|
||||
`;
|
||||
}
|
||||
);
|
||||
|
||||
return [content, demoLinks];
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
const hljs = require('highlight.js');
|
||||
|
||||
module.exports = function highlight(str, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
// https://github.com/highlightjs/highlight.js/issues/2277
|
||||
return hljs.highlight(str, { language: lang, ignoreIllegals: true }).value;
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
@ -1,117 +0,0 @@
|
||||
const path = require('path');
|
||||
const loaderUtils = require('loader-utils');
|
||||
const frontMatter = require('front-matter');
|
||||
const parser = require('./md-parser');
|
||||
const linkOpen = require('./link-open');
|
||||
const cardWrapper = require('./card-wrapper');
|
||||
const extractDemo = require('./extract-demo');
|
||||
const sideEffectTags = require('./side-effect-tags');
|
||||
|
||||
function camelize(str) {
|
||||
return `-${str}`.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : ''));
|
||||
}
|
||||
|
||||
const sharedVueOptions = `mounted() {
|
||||
const anchors = [].slice.call(this.$el.querySelectorAll('h2, h3, h4, h5'));
|
||||
|
||||
anchors.forEach(anchor => {
|
||||
anchor.addEventListener('click', this.scrollToAnchor);
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
scrollToAnchor(event) {
|
||||
if (event.target.id) {
|
||||
this.$router.push({
|
||||
name: this.$route.name,
|
||||
hash: '#' + event.target.id
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
`;
|
||||
|
||||
function wrapper(content) {
|
||||
let demoLinks;
|
||||
[content, demoLinks] = extractDemo.call(this, content);
|
||||
content = cardWrapper(content);
|
||||
|
||||
// 不包含 demo-code 的 md 文件,直接使绑定 HTML
|
||||
if (demoLinks.length === 0) {
|
||||
content = escape(content);
|
||||
|
||||
return `
|
||||
<script>
|
||||
import { h } from 'vue';
|
||||
|
||||
const content = unescape(\`${content}\`);
|
||||
|
||||
export default {
|
||||
${sharedVueOptions}
|
||||
|
||||
render() {
|
||||
return h('section', { innerHTML: content });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
`;
|
||||
}
|
||||
|
||||
// 包含 demo-code 的 md 文件,需要走模版渲染
|
||||
let styles;
|
||||
[content, styles] = sideEffectTags(content);
|
||||
|
||||
return `
|
||||
<template>
|
||||
<section v-once>
|
||||
${content}
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
${demoLinks
|
||||
.map((link) => {
|
||||
return `import DemoCode${camelize(
|
||||
path.basename(link, '.vue')
|
||||
)} from '${link}';`;
|
||||
})
|
||||
.join('\n')}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
${demoLinks
|
||||
.map((link) => `DemoCode${camelize(path.basename(link, '.vue'))}`)
|
||||
.join(',')}
|
||||
},
|
||||
|
||||
${sharedVueOptions}
|
||||
};
|
||||
</script>
|
||||
|
||||
${styles.join('\n')}
|
||||
`;
|
||||
}
|
||||
|
||||
module.exports = function (source) {
|
||||
let options = loaderUtils.getOptions(this) || {};
|
||||
this.cacheable && this.cacheable();
|
||||
|
||||
options = {
|
||||
wrapper,
|
||||
linkOpen: true,
|
||||
...options,
|
||||
};
|
||||
|
||||
let fm;
|
||||
|
||||
if (options.enableMetaData) {
|
||||
fm = frontMatter(source);
|
||||
source = fm.body;
|
||||
}
|
||||
|
||||
if (options.linkOpen) {
|
||||
linkOpen(parser);
|
||||
}
|
||||
|
||||
return options.wrapper.call(this, parser.render(source), fm);
|
||||
};
|
@ -1,18 +0,0 @@
|
||||
// add target="_blank" to all links
|
||||
module.exports = function linkOpen(md) {
|
||||
const defaultRender =
|
||||
md.renderer.rules.link_open ||
|
||||
function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
|
||||
md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
|
||||
const aIndex = tokens[idx].attrIndex('target');
|
||||
|
||||
if (aIndex < 0) {
|
||||
tokens[idx].attrPush(['target', '_blank']); // add new attribute
|
||||
}
|
||||
|
||||
return defaultRender(tokens, idx, options, env, self);
|
||||
};
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
const MarkdownIt = require('markdown-it');
|
||||
const markdownItAnchor = require('markdown-it-anchor');
|
||||
const highlight = require('./highlight');
|
||||
const { slugify } = require('transliteration');
|
||||
|
||||
const parser = new MarkdownIt({
|
||||
html: true,
|
||||
highlight,
|
||||
}).use(markdownItAnchor, {
|
||||
level: 2,
|
||||
slugify,
|
||||
});
|
||||
|
||||
module.exports = parser;
|
@ -1,14 +0,0 @@
|
||||
module.exports = function sideEffectTags(content) {
|
||||
const styles = [];
|
||||
|
||||
// 从模版中移除 script 标签
|
||||
content = content.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/g, '');
|
||||
|
||||
// 从模版中移除 style 标签,并收集到 styles 数组中,以转移为 .vue 文件 的 style 标签
|
||||
content = content.replace(/<style[\s\S]*?>([\s\S]*?)<\/style>/g, (_, css) => {
|
||||
styles.push(`<style scoped>${css}</style>`);
|
||||
return '';
|
||||
});
|
||||
|
||||
return [content, styles];
|
||||
};
|
@ -3,9 +3,9 @@ import { VueTag, VeturTags, VeturAttributes, VeturAttribute } from './type';
|
||||
export function genVeturTags(tags: VueTag[]) {
|
||||
const veturTags: VeturTags = {};
|
||||
|
||||
tags.forEach(tag => {
|
||||
tags.forEach((tag) => {
|
||||
veturTags[tag.name] = {
|
||||
attributes: tag.attributes ? tag.attributes.map(item => item.name) : [],
|
||||
attributes: tag.attributes ? tag.attributes.map((item) => item.name) : [],
|
||||
};
|
||||
});
|
||||
|
||||
@ -15,16 +15,16 @@ export function genVeturTags(tags: VueTag[]) {
|
||||
export function genVeturAttributes(tags: VueTag[]) {
|
||||
const veturAttributes: VeturAttributes = {};
|
||||
|
||||
tags.forEach(tag => {
|
||||
tags.forEach((tag) => {
|
||||
if (tag.attributes) {
|
||||
tag.attributes.forEach(attr => {
|
||||
let attribute: VeturAttribute = {
|
||||
tag.attributes.forEach((attr) => {
|
||||
const attribute: VeturAttribute = {
|
||||
type: attr.value.type,
|
||||
description: `${attr.description}, 默认值: ${attr.default}`
|
||||
}
|
||||
description: `${attr.description}, Default: ${attr.default}`,
|
||||
};
|
||||
|
||||
if (attr.options.length > 0) {
|
||||
attribute.options = attr.options
|
||||
attribute.options = attr.options;
|
||||
}
|
||||
|
||||
veturAttributes[`${tag.name}/${attr.name}`] = attribute;
|
||||
|
@ -11,6 +11,8 @@ function bundleBundle(format) {
|
||||
bundle: true,
|
||||
target: ['chrome53'],
|
||||
outfile,
|
||||
// preserve Chinese character
|
||||
charset: 'utf8',
|
||||
external: ['vue'],
|
||||
entryPoints: ['./src/index.ts'],
|
||||
}).then(finish);
|
||||
|
@ -34,7 +34,7 @@
|
||||
"esbuild": "^0.13.15",
|
||||
"release-it": "^14.0.2",
|
||||
"typescript": "~4.5.2",
|
||||
"vue": "^3.2.20"
|
||||
"vue": "^3.2.27"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
|
@ -1,11 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@vant/cli/preset.cjs',
|
||||
{
|
||||
loose: process.env.BUILD_TARGET === 'package',
|
||||
enableObjectSlots: false,
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
@ -16,6 +16,94 @@ Vant follows [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/).
|
||||
|
||||
## Details
|
||||
|
||||
### [v3.4.2](https://github.com/compare/v3.4.1...v3.4.2)
|
||||
|
||||
`2022-01-17`
|
||||
|
||||
**Feature**
|
||||
|
||||
- Cascader: add show-header prop [#10202](https://github.com/youzan/vant/issues/10202)
|
||||
- Image: add position prop [#10142](https://github.com/youzan/vant/issues/10142)
|
||||
- ImagePreview: improve zoom fluency [#10187](https://github.com/youzan/vant/issues/10187)
|
||||
- Overlay: add lazy-render prop [#10180](https://github.com/youzan/vant/issues/10180)
|
||||
- provide english version of web-types [#10207](https://github.com/youzan/vant/issues/10207)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Calendar: incorrectly selected when a date is disabled [#10196](https://github.com/youzan/vant/issues/10196)
|
||||
- Image: failed to hide loading when using lazy-load [#10193](https://github.com/youzan/vant/issues/10193)
|
||||
- ImagePreview: incorrectly closed after zooming [#10188](https://github.com/youzan/vant/issues/10188)
|
||||
- Skeleton: row prop can't be string type [#10172](https://github.com/youzan/vant/issues/10172)
|
||||
- useHeight may get the wrong height [#10195](https://github.com/youzan/vant/issues/10195)
|
||||
|
||||
### [v3.4.1](https://github.com/compare/v3.4.0...v3.4.1)
|
||||
|
||||
`2022-01-10`
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Area: missing picker mask [#10164](https://github.com/youzan/vant/issues/10164)
|
||||
- DatetimePicker: error in some edge cases [#10140](https://github.com/youzan/vant/issues/10140)
|
||||
- Popover: fix gap under the triangle [#10148](https://github.com/youzan/vant/issues/10148)
|
||||
|
||||
### [v3.4.0](https://github.com/compare/v3.3.7...v3.4.0)
|
||||
|
||||
`2022-01-01`
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Icons: complete https protocol [#10079](https://github.com/youzan/vant/issues/10079)
|
||||
- Picker: should not render mask and frame when options is empty [#10135](https://github.com/youzan/vant/issues/10135)
|
||||
- Popup: close event emitted twice [#10132](https://github.com/youzan/vant/issues/10132)
|
||||
- PullRefresh: may trigger browser bounce in some cases [#10080](https://github.com/youzan/vant/issues/10080)
|
||||
- Step: fix inactive title style [#10049](https://github.com/youzan/vant/issues/10049)
|
||||
- SwipeCell: should not trigger open event when opened [#10059](https://github.com/youzan/vant/issues/10059)
|
||||
- swipe: delay load cause swipe error [#10052](https://github.com/youzan/vant/issues/10052) [#10069](https://github.com/youzan/vant/issues/10069)
|
||||
- Tabs: should not render line when have no tab [#10063](https://github.com/youzan/vant/issues/10063)
|
||||
|
||||
**Feature**
|
||||
|
||||
- ActionBarIcon: add badge-props prop [#10096](https://github.com/youzan/vant/issues/10096)
|
||||
- ActionSheet: add option slot [#10065](https://github.com/youzan/vant/issues/10065)
|
||||
- Badge: add badge-props prop [#10095](https://github.com/youzan/vant/issues/10095)
|
||||
- GridItem: add badge-props prop [#10097](https://github.com/youzan/vant/issues/10097)
|
||||
- Icons: add cash-o icon [#10076](https://github.com/youzan/vant/issues/10076)
|
||||
- ImagePreview: add overlayClass option [#10044](https://github.com/youzan/vant/issues/10044)
|
||||
- Notify: add position prop [#10056](https://github.com/youzan/vant/issues/10056)
|
||||
- Popover: add action slot [#10091](https://github.com/youzan/vant/issues/10091)
|
||||
- Search: add click-left-icon、click-right-icon event [#10139](https://github.com/youzan/vant/issues/10139)
|
||||
- SidebarItem: add badge-props prop [#10106](https://github.com/youzan/vant/issues/10106)
|
||||
- Swipe: indicator slot add total param [#10060](https://github.com/youzan/vant/issues/10060)
|
||||
- TabbarItem: add badge-props prop [#10092](https://github.com/youzan/vant/issues/10092)
|
||||
- Tabs: add shrink prop [#10125](https://github.com/youzan/vant/issues/10125)
|
||||
|
||||
**style**
|
||||
|
||||
- PullRefresh: remove user-select: none [#10078](https://github.com/youzan/vant/issues/10078)
|
||||
- TreeSelect: allow select text in content slot [#10081](https://github.com/youzan/vant/issues/10081)
|
||||
|
||||
**Types**
|
||||
|
||||
- define global components for volar [#10136](https://github.com/youzan/vant/issues/10136)
|
||||
- Field: type prop allow all native types [#10042](https://github.com/youzan/vant/issues/10042)
|
||||
- Popup: add PopupInstance type [#10062](https://github.com/youzan/vant/issues/10062)
|
||||
- Search: fix missing event typing [#10134](https://github.com/youzan/vant/issues/10134)
|
||||
|
||||
### [v3.3.7](https://github.com/compare/v3.3.6...v3.3.7)
|
||||
|
||||
`2021-12-12`
|
||||
|
||||
**Feature**
|
||||
|
||||
- Badge: add position prop [#10024](https://github.com/youzan/vant/issues/10024)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- DatetimePicker: should update value after calling picker methods [#10029](https://github.com/youzan/vant/issues/10029)
|
||||
- Field: fix the length of emoji [#10033](https://github.com/youzan/vant/issues/10033)
|
||||
- Pagination: change event not work [#10018](https://github.com/youzan/vant/issues/10018)
|
||||
- fix tree shaking is broken [#10034](https://github.com/youzan/vant/issues/10034)
|
||||
|
||||
### [v3.3.6](https://github.com/compare/v3.3.5...v3.3.6)
|
||||
|
||||
`2021-12-05`
|
||||
|
@ -16,6 +16,95 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。
|
||||
|
||||
## 更新内容
|
||||
|
||||
### [v3.4.2](https://github.com/compare/v3.4.1...v3.4.2)
|
||||
|
||||
`2022-01-17`
|
||||
|
||||
**Feature**
|
||||
|
||||
- Cascader: 新增 show-header 属性 [#10202](https://github.com/youzan/vant/issues/10202)
|
||||
- Image: 新增 position 属性 [#10142](https://github.com/youzan/vant/issues/10142)
|
||||
- ImagePreview: 优化缩放手势的流畅度 [#10187](https://github.com/youzan/vant/issues/10187)
|
||||
- Overlay: 新增 lazy-render 属性 [#10180](https://github.com/youzan/vant/issues/10180)
|
||||
- web-types.json 现在默认使用英文描述 [#10207](https://github.com/youzan/vant/issues/10207)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Calendar: 修复范围选择包括被禁用的日期时可能选择错误的问题 [#10196](https://github.com/youzan/vant/issues/10196)
|
||||
- Image: 修复使用 lazy-load 时可能无法正常加载的问题 [#10193](https://github.com/youzan/vant/issues/10193)
|
||||
- ImagePreview: 修复快速缩放手势导致预览关闭的问题 [#10188](https://github.com/youzan/vant/issues/10188)
|
||||
- Skeleton: 修复 row 属性为字符串类型时不生效的问题 [#10172](https://github.com/youzan/vant/issues/10172)
|
||||
- NavBar: 修复在 safari 上占位元素高度错误的问题 [#10195](https://github.com/youzan/vant/issues/10195)
|
||||
- Tabbar: 修复在 safari 上占位元素高度错误的问题 [#10195](https://github.com/youzan/vant/issues/10195)
|
||||
|
||||
### [v3.4.1](https://github.com/compare/v3.4.0...v3.4.1)
|
||||
|
||||
`2022-01-10`
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Area: 修复缺少遮罩层的问题 [#10164](https://github.com/youzan/vant/issues/10164)
|
||||
- DatetimePicker: 修复边界场景下出现报错的问题 [#10140](https://github.com/youzan/vant/issues/10140)
|
||||
- Popover: 修复箭头和弹出框之间存在缝隙的问题 [#10148](https://github.com/youzan/vant/issues/10148)
|
||||
|
||||
### [v3.4.0](https://github.com/compare/v3.3.7...v3.4.0)
|
||||
|
||||
`2022-01-01`
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Icons: 修复 URL 缺少协议导致个别浏览器出现异常的问题 [#10079](https://github.com/youzan/vant/issues/10079)
|
||||
- Picker: 修复选项为空时也会渲染选择框的问题 [#10135](https://github.com/youzan/vant/issues/10135)
|
||||
- Popup: 修复 close 事件触发两次的问题 [#10132](https://github.com/youzan/vant/issues/10132)
|
||||
- PullRefresh: 修复在个别浏览器上会触发原生回弹效果的问题 [#10080](https://github.com/youzan/vant/issues/10080)
|
||||
- Step: 修复 inactive-color 属性未正确生效的问题 [#10049](https://github.com/youzan/vant/issues/10049)
|
||||
- SwipeCell: 修复打开状态下也会触发 open 事件的问题 [#10059](https://github.com/youzan/vant/issues/10059)
|
||||
- swipe: 修复个别情况下无法正确滚动的问题 [#10052](https://github.com/youzan/vant/issues/10052) [#10069](https://github.com/youzan/vant/issues/10069)
|
||||
- Tabs: 修复标签页为空时会渲染一个错误的底部条的问题 [#10063](https://github.com/youzan/vant/issues/10063)
|
||||
|
||||
**Feature**
|
||||
|
||||
- ActionBarIcon: 新增 badge-props 属性 [#10096](https://github.com/youzan/vant/issues/10096)
|
||||
- ActionSheet: 新增 option 插槽 [#10065](https://github.com/youzan/vant/issues/10065)
|
||||
- Badge: 新增 badge-props 属性 [#10095](https://github.com/youzan/vant/issues/10095)
|
||||
- GridItem: 新增 badge-props 属性 [#10097](https://github.com/youzan/vant/issues/10097)
|
||||
- Icons: 新增 cash-o 图标 [#10076](https://github.com/youzan/vant/issues/10076)
|
||||
- ImagePreview: 新增 overlayClass 选项 [#10044](https://github.com/youzan/vant/issues/10044)
|
||||
- Notify: 新增 position 属性 [#10056](https://github.com/youzan/vant/issues/10056)
|
||||
- Popover: 新增 action 插槽 [#10091](https://github.com/youzan/vant/issues/10091)
|
||||
- Search: 新增 click-left-icon、click-right-icon 事件 [#10139](https://github.com/youzan/vant/issues/10139)
|
||||
- SidebarItem: 新增 badge-props 属性 [#10106](https://github.com/youzan/vant/issues/10106)
|
||||
- Swipe: indicator 插槽新增 total 参数 [#10060](https://github.com/youzan/vant/issues/10060)
|
||||
- TabbarItem: 新增 badge-props 属性 [#10092](https://github.com/youzan/vant/issues/10092)
|
||||
- Tabs: 新增 shrink 属性 [#10125](https://github.com/youzan/vant/issues/10125)
|
||||
|
||||
**style**
|
||||
|
||||
- PullRefresh: 移除 `user-select: none` 样式 [#10078](https://github.com/youzan/vant/issues/10078)
|
||||
- TreeSelect: 允许选中 content 插槽中的文字 [#10081](https://github.com/youzan/vant/issues/10081)
|
||||
|
||||
**Types**
|
||||
|
||||
- 增加所有组件的全局类型,在 volar 中提供默认提示 [#10136](https://github.com/youzan/vant/issues/10136)
|
||||
- Field: 修复 type 属性定义不全的问题 [#10042](https://github.com/youzan/vant/issues/10042)
|
||||
- Popup: 导出 PopupInstance 类型 [#10062](https://github.com/youzan/vant/issues/10062)
|
||||
- Search: 修复事件类型定义不全的问题 [#10134](https://github.com/youzan/vant/issues/10134)
|
||||
|
||||
### [v3.3.7](https://github.com/compare/v3.3.6...v3.3.7)
|
||||
|
||||
`2021-12-12`
|
||||
|
||||
**Feature**
|
||||
|
||||
- Badge: 新增 position 属性 [#10024](https://github.com/youzan/vant/issues/10024)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- DatetimePicker: 修复调用 Picker 实例方法后日期未正确更新的问题 [#10029](https://github.com/youzan/vant/issues/10029)
|
||||
- Field: 修复输入内容包含 emoji 时,长度计算错误的问题 [#10033](https://github.com/youzan/vant/issues/10033)
|
||||
- Pagination: 修复 change 事件不触发的问题 [#10018](https://github.com/youzan/vant/issues/10018)
|
||||
- 修复 tree shaking 不生效的问题 [#10034](https://github.com/youzan/vant/issues/10034)
|
||||
|
||||
### [v3.3.6](https://github.com/compare/v3.3.5...v3.3.6)
|
||||
|
||||
`2021-12-05`
|
||||
@ -59,15 +148,15 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。
|
||||
|
||||
**Feature**
|
||||
|
||||
- 新增 `package.json` 中的 `exports` 字段 [#9952](https://github.com/issues/9952)
|
||||
- Tabbar: 支持在 route 模式下匹配子路由 [#9926](https://github.com/issues/9926)
|
||||
- Tabs: 将 `van-tab__pane-wrapper` 类重命名为 `van-tab__panel-wrapper` [#9951](https://github.com/issues/9951)
|
||||
- 新增 `package.json` 中的 `exports` 字段 [#9952](https://github.com/youzan/vant/issues/9952)
|
||||
- Tabbar: 支持在 route 模式下匹配子路由 [#9926](https://github.com/youzan/vant/issues/9926)
|
||||
- Tabs: 将 `van-tab__pane-wrapper` 类重命名为 `van-tab__panel-wrapper` [#9951](https://github.com/youzan/vant/issues/9951)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Calendar: 修复 show-confirm 为 false 时不会限制最大日期范围的问题 [#9948](https://github.com/issues/9948)
|
||||
- Calendar: 修复 `scrollToDate` 方法无法精确滚动到对应日期的问题 [#9949](https://github.com/issues/9949)
|
||||
- Swipe: 修复开始滑动时未阻止 touchmove 事件行为的问题 [#9920](https://github.com/issues/9920)
|
||||
- Calendar: 修复 show-confirm 为 false 时不会限制最大日期范围的问题 [#9948](https://github.com/youzan/vant/issues/9948)
|
||||
- Calendar: 修复 `scrollToDate` 方法无法精确滚动到对应日期的问题 [#9949](https://github.com/youzan/vant/issues/9949)
|
||||
- Swipe: 修复开始滑动时未阻止 touchmove 事件行为的问题 [#9920](https://github.com/youzan/vant/issues/9920)
|
||||
|
||||
### [v3.3.1](https://github.com/compare/v3.3.0...v3.3.1)
|
||||
|
||||
@ -75,7 +164,7 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- AddressEdit: 修复表单校验不通过时也会触发 save 事件的问题 [#9917](https://github.com/issues/9917)
|
||||
- AddressEdit: 修复表单校验不通过时也会触发 save 事件的问题 [#9917](https://github.com/youzan/vant/issues/9917)
|
||||
|
||||
### [v3.3.0](https://github.com/compare/v3.2.8...v3.3.0)
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
### Issue 规范
|
||||
|
||||
- 遇到问题时,请先确认这个问题是否已经在 issue 中有记录或者已被修复
|
||||
- 提 issue 时,请用简短的语言描述遇到的问题,并添加出现问题时的环境和复现步骤
|
||||
- 遇到问题时,请先确认这个问题是否已经在 issue 中有记录或者已被修复。
|
||||
- 提 issue 时,请用简短的语言描述遇到的问题,并添加出现问题时的环境和复现步骤。
|
||||
|
||||
## 参与开发
|
||||
|
||||
@ -71,28 +71,38 @@ src
|
||||
└─ README.zh-CN.md # 中文文档
|
||||
```
|
||||
|
||||
### 代码规范
|
||||
|
||||
在编写代码时,请注意:
|
||||
|
||||
- 确保代码可以通过仓库的 ESLint 和 Stylelint 校验。
|
||||
- 确保代码格式是规范的,使用 prettier 进行代码格式化。
|
||||
- 确保没有使用超出兼容性范围的 API,比如 `async/await`。
|
||||
|
||||
## 提交 PR
|
||||
|
||||
### Pull Request 规范
|
||||
### 参考指南
|
||||
|
||||
如果你是第一次在 GitHub 上提 Pull Request ,可以阅读下面这两篇文章来学习:
|
||||
|
||||
- [如何优雅地在 GitHub 上贡献代码](https://segmentfault.com/a/1190000000736629)
|
||||
- [第一次参与开源](https://github.com/firstcontributions/first-contributions/blob/master/translations/README.chs.md)
|
||||
|
||||
#### 规范
|
||||
### Pull Request 规范
|
||||
|
||||
- 如果遇到问题,建议保持你的 PR 足够小。保证一个 PR 只解决一个问题或只添加一个功能
|
||||
- 当新增组件或者修改原有组件时,记得增加或者修改测试代码,保证代码的稳定
|
||||
- 在 PR 中请添加合适的描述,并关联相关的 Issue
|
||||
在提交 Pull Request 时,请注意:
|
||||
|
||||
- 如果遇到问题,建议保持你的 PR 足够小。保证一个 PR 只解决单个问题、添加单个功能。
|
||||
- 当新增组件或者修改原有组件时,记得增加或者修改对应的单元测试,保证代码的稳定。
|
||||
- 在 PR 中请添加合适的描述,并关联相关的 Issue。
|
||||
|
||||
### Pull Request 流程
|
||||
|
||||
1. fork 主仓库,如果已经 fork 过,请同步主仓库的最新代码
|
||||
2. 基于 fork 后仓库的 dev 分支新建一个分支,比如 `feature/button_color`
|
||||
3. 在新分支上进行开发,开发完成后,提 Pull Request 到主仓库的 dev 分支
|
||||
4. Pull Request 会在 Review 通过后被合并到主仓库
|
||||
5. 等待 Vant 发布版本,一般是每周一次
|
||||
1. fork 主仓库,如果已经 fork 过,请同步主仓库的最新代码。
|
||||
2. 基于 fork 后仓库的 dev 分支新建一个分支,比如 `feature/button_color`。
|
||||
3. 在新分支上进行开发,开发完成后,提 Pull Request 到主仓库的 dev 分支。
|
||||
4. Pull Request 会在 Review 通过后被合并到主仓库。
|
||||
5. 等待 Vant 发布新版本,一般是每周一次。
|
||||
|
||||
### 同步最新代码
|
||||
|
||||
|
@ -48,7 +48,7 @@ Vant 3 supports modern browsers and Chrome >= 51、iOS >= 10.0 (same as Vue 3).
|
||||
| Project | Description |
|
||||
| --- | --- |
|
||||
| [3lang3/react-vant](https://github.com/3lang3/react-vant) | React mobile UI Components based on Vant |
|
||||
| [mxdi9i7/vant-react](https://github.com/mxdi9i7/vant-react) | Mobile UI Components built on React and TS, inspired by Vant |
|
||||
| [rc-ui-lib](https://github.com/rancui/rc-ui-lib) | React Mobile UI Components Library |
|
||||
| [vant-aliapp](https://github.com/ant-move/Vant-Aliapp) | Alipay MiniProgram UI |
|
||||
| [taroify](https://gitee.com/mallfoundry/taroify) | Vant Taro |
|
||||
| [vant-theme](https://github.com/Aisen60/vant-theme) | Online theme preview built on Vant UI |
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
### 介绍
|
||||
|
||||
Vant 是**有赞前端团队**开源的移动端组件库,于 2017 年开源,已持续维护 4 年时间。Vant 对内承载了有赞所有核心业务,对外服务十多万开发者,是业界主流的移动端组件库之一。
|
||||
Vant 是**有赞前端团队**开源的移动端组件库,于 2017 年开源。Vant 对内承载了有赞所有核心业务,对外服务十多万开发者,是业界主流的移动端组件库之一。
|
||||
|
||||
目前 Vant 官方提供了 [Vue 2 版本](https://vant-contrib.gitee.io/vant)、[Vue 3 版本](https://vant-contrib.gitee.io/vant/v3)和[微信小程序版本](http://vant-contrib.gitee.io/vant-weapp),并由社区团队维护 [React 版本](https://github.com/mxdi9i7/vant-react)和[支付宝小程序版本](https://github.com/ant-move/Vant-Aliapp)。
|
||||
|
||||
@ -62,7 +62,7 @@ Vant 3 支持现代浏览器以及 Chrome >= 51、iOS >= 10.0(与 Vue 3 一致
|
||||
| 项目 | 描述 |
|
||||
| --- | --- |
|
||||
| [3lang3/react-vant](https://github.com/3lang3/react-vant) | 参照 Vant 打造的 React 移动端组件库 |
|
||||
| [mxdi9i7/vant-react](https://github.com/mxdi9i7/vant-react) | 基于 React 和 TS 构建的移动端组件库 |
|
||||
| [rc-ui-lib](https://github.com/rancui/rc-ui-lib) | 基于 Vant 的 React 版本移动端 UI 组件库 |
|
||||
| [vant-aliapp](https://github.com/ant-move/Vant-Aliapp) | Vant 支付宝小程序版 |
|
||||
| [taroify](https://gitee.com/mallfoundry/taroify) | Vant Taro 版 |
|
||||
| [vant-theme](https://github.com/Aisen60/vant-theme) | Vant 在线主题预览工具 |
|
||||
|
@ -99,7 +99,14 @@ If you are using vite, please use [vite-plugin-style-import](https://github.com/
|
||||
#### 1. Install Plugin
|
||||
|
||||
```bash
|
||||
npm i vite-plugin-style-import@1.2.0 -D
|
||||
# with npm
|
||||
npm i vite-plugin-style-import -D
|
||||
|
||||
# with yarn
|
||||
yarn add vite-plugin-style-import -D
|
||||
|
||||
# with pnpm
|
||||
pnpm add vite-plugin-style-import -D
|
||||
```
|
||||
|
||||
#### 2. Configure Plugin
|
||||
@ -108,19 +115,13 @@ Configure the plugin in the `vite.config.js` file:
|
||||
|
||||
```js
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import styleImport from 'vite-plugin-style-import';
|
||||
import styleImport, { VantResolve } from 'vite-plugin-style-import';
|
||||
|
||||
export default {
|
||||
plugins: [
|
||||
vue(),
|
||||
styleImport({
|
||||
libs: [
|
||||
{
|
||||
libraryName: 'vant',
|
||||
esModule: true,
|
||||
resolveStyle: (name) => `vant/es/${name}/style/index`,
|
||||
},
|
||||
],
|
||||
resolves: [VantResolve()],
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
@ -100,7 +100,14 @@ pnpm add vant@3
|
||||
#### 1. 安装插件
|
||||
|
||||
```bash
|
||||
npm i vite-plugin-style-import@1.2.0 -D
|
||||
# 通过 npm 安装
|
||||
npm i vite-plugin-style-import -D
|
||||
|
||||
# 通过 yarn 安装
|
||||
yarn add vite-plugin-style-import -D
|
||||
|
||||
# 通过 pnpm 安装
|
||||
pnpm add vite-plugin-style-import -D
|
||||
```
|
||||
|
||||
#### 2. 配置插件
|
||||
@ -109,19 +116,13 @@ npm i vite-plugin-style-import@1.2.0 -D
|
||||
|
||||
```js
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import styleImport from 'vite-plugin-style-import';
|
||||
import styleImport, { VantResolve } from 'vite-plugin-style-import';
|
||||
|
||||
export default {
|
||||
plugins: [
|
||||
vue(),
|
||||
styleImport({
|
||||
libs: [
|
||||
{
|
||||
libraryName: 'vant',
|
||||
esModule: true,
|
||||
resolveStyle: (name) => `vant/es/${name}/style/index`,
|
||||
},
|
||||
],
|
||||
resolves: [VantResolve()],
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
@ -4,6 +4,21 @@
|
||||
|
||||
Vant provide some built-in composition APIs, you can directly use these APIs for development.
|
||||
|
||||
### Install
|
||||
|
||||
Although `@vant/use` is already included in Vant's dependencies, it is still recommended to install this package explicitly:
|
||||
|
||||
```shell
|
||||
# with npm
|
||||
npm i @vant/use
|
||||
|
||||
# with yarn
|
||||
yarn add @vant/use
|
||||
|
||||
# with pnpm
|
||||
pnpm add @vant/use
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
```js
|
||||
|
@ -2,7 +2,22 @@
|
||||
|
||||
### 介绍
|
||||
|
||||
Vant 内置了一系列的组合式 API,对于安装了 `vant` 的项目,可以直接使用这些 API 进行开发。
|
||||
Vant 底层依赖了 `@vant/use` 包,其中内置了一系列的组合式 API。对于使用了 Vant 的项目,可以复用这些 API 进行开发。
|
||||
|
||||
### 安装
|
||||
|
||||
虽然 Vant 的依赖中已经包含了 `@vant/use`,但我们仍然推荐显式地安装它:
|
||||
|
||||
```shell
|
||||
# with npm
|
||||
npm i @vant/use
|
||||
|
||||
# with yarn
|
||||
yarn add @vant/use
|
||||
|
||||
# with pnpm
|
||||
pnpm add @vant/use
|
||||
```
|
||||
|
||||
### 示例
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "vant",
|
||||
"version": "3.3.6",
|
||||
"version": "3.4.2",
|
||||
"description": "Mobile UI Components built on Vue",
|
||||
"main": "lib/vant.cjs.js",
|
||||
"module": "lib/vant.es.js",
|
||||
"module": "es/index.js",
|
||||
"style": "lib/index.css",
|
||||
"typings": "lib/index.d.ts",
|
||||
"unpkg": "lib/vant.min.js",
|
||||
@ -14,11 +14,11 @@
|
||||
"import": "./lib/ssr.mjs",
|
||||
"require": "./lib/ssr.js"
|
||||
},
|
||||
"import": "./lib/vant.es.js",
|
||||
"import": "./es/index.js",
|
||||
"require": "./lib/vant.cjs.js",
|
||||
"types": "./lib/index.d.ts"
|
||||
},
|
||||
"./es": "./lib/vant.es.js",
|
||||
"./es": "./es/index.js",
|
||||
"./lib": "./lib/vant.cjs.js",
|
||||
"./es/": "./es/",
|
||||
"./lib/": "./lib/",
|
||||
@ -75,11 +75,10 @@
|
||||
"@vant/area-data": "^1.1.3",
|
||||
"@vant/cli": "workspace:*",
|
||||
"@vant/eslint-config": "workspace:*",
|
||||
"@vue/compiler-sfc": "^3.2.20",
|
||||
"@vue/runtime-core": "^3.2.20",
|
||||
"@vue/runtime-core": "^3.2.27",
|
||||
"@vue/test-utils": "^2.0.0-rc.16",
|
||||
"typescript": "~4.5.2",
|
||||
"vue": "^3.2.20",
|
||||
"vue": "^3.2.27",
|
||||
"vue-router": "^4.0.12"
|
||||
},
|
||||
"sideEffects": [
|
||||
|
@ -1,4 +1,9 @@
|
||||
import { computed, PropType, defineComponent, ExtractPropTypes } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
type PropType,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
import { extend, createNamespace } from '../utils';
|
||||
import { ACTION_BAR_KEY } from '../action-bar/ActionBar';
|
||||
|
||||
|
@ -4,3 +4,9 @@ import _ActionBarButton from './ActionBarButton';
|
||||
export const ActionBarButton = withInstall(_ActionBarButton);
|
||||
export default ActionBarButton;
|
||||
export type { ActionBarButtonProps } from './ActionBarButton';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanActionBarButton: typeof ActionBarButton;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { defineComponent, ExtractPropTypes } from 'vue';
|
||||
import { defineComponent, type PropType, type ExtractPropTypes } from 'vue';
|
||||
import { extend, createNamespace, unknownProp, numericProp } from '../utils';
|
||||
import { ACTION_BAR_KEY } from '../action-bar/ActionBar';
|
||||
|
||||
@ -8,7 +8,7 @@ import { useRoute, routeProps } from '../composables/use-route';
|
||||
|
||||
// Components
|
||||
import { Icon } from '../icon';
|
||||
import { Badge } from '../badge';
|
||||
import { Badge, type BadgeProps } from '../badge';
|
||||
|
||||
const [name, bem] = createNamespace('action-bar-icon');
|
||||
|
||||
@ -19,6 +19,7 @@ const actionBarIconProps = extend({}, routeProps, {
|
||||
color: String,
|
||||
badge: numericProp,
|
||||
iconClass: unknownProp,
|
||||
badgeProps: Object as PropType<Partial<BadgeProps>>,
|
||||
iconPrefix: String,
|
||||
});
|
||||
|
||||
@ -35,15 +36,17 @@ export default defineComponent({
|
||||
useParent(ACTION_BAR_KEY);
|
||||
|
||||
const renderIcon = () => {
|
||||
const { dot, badge, icon, color, iconClass, iconPrefix } = props;
|
||||
const { dot, badge, icon, color, iconClass, badgeProps, iconPrefix } =
|
||||
props;
|
||||
|
||||
if (slots.icon) {
|
||||
return (
|
||||
<Badge
|
||||
v-slots={{ default: slots.icon }}
|
||||
dot={dot}
|
||||
content={badge}
|
||||
class={bem('icon')}
|
||||
content={badge}
|
||||
{...badgeProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -56,6 +59,7 @@ export default defineComponent({
|
||||
badge={badge}
|
||||
color={color}
|
||||
class={[bem('icon'), iconClass]}
|
||||
badgeProps={badgeProps}
|
||||
classPrefix={iconPrefix}
|
||||
/>
|
||||
);
|
||||
|
@ -4,3 +4,9 @@ import _ActionBarIcon from './ActionBarIcon';
|
||||
export const ActionBarIcon = withInstall(_ActionBarIcon);
|
||||
export default ActionBarIcon;
|
||||
export type { ActionBarIconProps } from './ActionBarIcon';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanActionBarIcon: typeof ActionBarIcon;
|
||||
}
|
||||
}
|
||||
|
@ -59,3 +59,17 @@ test('should render icon slot with dot correctly', () => {
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render badge-props prop correctly', async () => {
|
||||
const wrapper = mount(ActionBarIcon, {
|
||||
props: {
|
||||
badge: 1,
|
||||
badgeProps: {
|
||||
color: 'blue',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const badge = wrapper.find('.van-badge');
|
||||
expect(badge.style.backgroundColor).toEqual('blue');
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { defineComponent, ExtractPropTypes } from 'vue';
|
||||
import { defineComponent, type ExtractPropTypes } from 'vue';
|
||||
import { truthProp, createNamespace } from '../utils';
|
||||
import { useChildren } from '@vant/use';
|
||||
|
||||
|
@ -102,7 +102,8 @@ Use `badge` prop to show badge in icon.
|
||||
| icon-prefix `v3.0.17` | Icon className prefix | _string_ | `van-icon` |
|
||||
| dot | Whether to show red dot | _boolean_ | - |
|
||||
| badge | Content of the badge | _number \| string_ | - |
|
||||
| url | Link | _string_ | - |
|
||||
| badge-props `v3.2.8` | Props of Badge,see [Badge - props](#/en-US/badge#props) | _BadgeProps_ | - |
|
||||
| url | Link URL | _string_ | - |
|
||||
| to | Target route of the link, same as to of vue-router | _string \| object_ | - |
|
||||
| replace | If true, the navigation will not leave a history record | _boolean_ | `false` |
|
||||
|
||||
@ -115,7 +116,7 @@ Use `badge` prop to show badge in icon.
|
||||
| color | Button color, support linear-gradient | _string_ | - |
|
||||
| icon | Left Icon | _string_ | - |
|
||||
| disabled | Whether to disable button | _boolean_ | `false` |
|
||||
| loading | Whether show loading status | _boolean_ | `false` |
|
||||
| loading | Whether to show loading status | _boolean_ | `false` |
|
||||
| url | Link | _string_ | - |
|
||||
| to | Target route of the link, same as to of vue-router | _string \| object_ | - |
|
||||
| replace | If true, the navigation will not leave a history record | _boolean_ | `false` |
|
||||
|
@ -106,6 +106,7 @@ export default {
|
||||
| icon-prefix `v3.0.17` | 图标类名前缀,等同于 Icon 组件的 [class-prefix 属性](#/zh-CN/icon#props) | _string_ | `van-icon` |
|
||||
| dot | 是否显示图标右上角小红点 | _boolean_ | `false` |
|
||||
| badge | 图标右上角徽标的内容 | _number \| string_ | - |
|
||||
| badge-props `v3.2.8` | 自定义徽标的属性,传入的对象会被透传给 [Badge 组件的 props](#/zh-CN/badge#props) | _BadgeProps_ | - |
|
||||
| url | 点击后跳转的链接地址 | _string_ | - |
|
||||
| to | 点击后跳转的目标路由对象,等同于 vue-router 的 [to 属性](https://router.vuejs.org/zh/api/#to) | _string \| object_ | - |
|
||||
| replace | 是否在跳转时替换当前页面历史 | _boolean_ | `false` |
|
||||
@ -117,7 +118,7 @@ export default {
|
||||
| text | 按钮文字 | _string_ | - |
|
||||
| type | 按钮类型,可选值为 `primary` `info` `warning` `danger` | _string_ | `default` |
|
||||
| color | 按钮颜色,支持传入 `linear-gradient` 渐变色 | _string_ | - |
|
||||
| icon | 左侧[图标名称](#/zh-CN/icon)或图片链接 | _string_ | - |
|
||||
| icon | 左侧图标名称或图片链接,等同于 Icon 组件的 [name 属性](#/zh-CN/icon#props) | _string_ | - |
|
||||
| disabled | 是否禁用按钮 | _boolean_ | `false` |
|
||||
| loading | 是否显示为加载状态 | _boolean_ | `false` |
|
||||
| url | 点击后跳转的链接地址 | _string_ | - |
|
||||
|
@ -4,3 +4,9 @@ import _ActionBar from './ActionBar';
|
||||
export const ActionBar = withInstall(_ActionBar);
|
||||
export default ActionBar;
|
||||
export type { ActionBarProps } from './ActionBar';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanActionBar: typeof ActionBar;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { nextTick, defineComponent, ExtractPropTypes } from 'vue';
|
||||
import { nextTick, defineComponent, type ExtractPropTypes } from 'vue';
|
||||
|
||||
// Utils
|
||||
import {
|
||||
@ -94,18 +94,23 @@ export default defineComponent({
|
||||
}
|
||||
};
|
||||
|
||||
const renderOption = (item: ActionSheetAction, index: number) => {
|
||||
const { name, color, subname, loading, callback, disabled, className } =
|
||||
item;
|
||||
const renderActionContent = (action: ActionSheetAction, index: number) => {
|
||||
if (action.loading) {
|
||||
return <Loading class={bem('loading-icon')} />;
|
||||
}
|
||||
|
||||
const Content = loading ? (
|
||||
<Loading class={bem('loading-icon')} />
|
||||
) : (
|
||||
[
|
||||
<span class={bem('name')}>{name}</span>,
|
||||
subname && <div class={bem('subname')}>{subname}</div>,
|
||||
]
|
||||
);
|
||||
if (slots.action) {
|
||||
return slots.action({ action, index });
|
||||
}
|
||||
|
||||
return [
|
||||
<span class={bem('name')}>{action.name}</span>,
|
||||
action.subname && <div class={bem('subname')}>{action.subname}</div>,
|
||||
];
|
||||
};
|
||||
|
||||
const renderAction = (action: ActionSheetAction, index: number) => {
|
||||
const { color, loading, callback, disabled, className } = action;
|
||||
|
||||
const onClick = () => {
|
||||
if (disabled || loading) {
|
||||
@ -113,14 +118,14 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback(item);
|
||||
callback(action);
|
||||
}
|
||||
|
||||
if (props.closeOnClickAction) {
|
||||
updateShow(false);
|
||||
}
|
||||
|
||||
nextTick(() => emit('select', item, index));
|
||||
nextTick(() => emit('select', action, index));
|
||||
};
|
||||
|
||||
return (
|
||||
@ -130,7 +135,7 @@ export default defineComponent({
|
||||
class={[bem('item', { loading, disabled }), className]}
|
||||
onClick={onClick}
|
||||
>
|
||||
{Content}
|
||||
{renderActionContent(action, index)}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@ -154,7 +159,7 @@ export default defineComponent({
|
||||
{renderHeader()}
|
||||
{renderDescription()}
|
||||
<div class={bem('content')}>
|
||||
{props.actions.map(renderOption)}
|
||||
{props.actions.map(renderAction)}
|
||||
{slots.default?.()}
|
||||
</div>
|
||||
{renderCancel()}
|
||||
|
@ -218,11 +218,12 @@ export default {
|
||||
|
||||
### Slots
|
||||
|
||||
| Name | Description |
|
||||
| ---------------- | ------------------------------------ |
|
||||
| default | Custom content |
|
||||
| description | Custom description above the options |
|
||||
| cancel `v3.0.10` | Custom the content of cancel button |
|
||||
| Name | Description | SlotProps |
|
||||
| --- | --- | --- |
|
||||
| default | Custom content |
|
||||
| description | Custom description above the options |
|
||||
| cancel `v3.0.10` | Custom the content of cancel button |
|
||||
| action `v3.4.0` | Custom the content of action | _{ action: ActionSheetAction, index: number }_ |
|
||||
|
||||
### Types
|
||||
|
||||
|
@ -187,7 +187,7 @@ export default {
|
||||
| cancel-text | 取消按钮文字 | _string_ | - |
|
||||
| description | 选项上方的描述信息 | _string_ | - |
|
||||
| closeable | 是否显示关闭图标 | _boolean_ | `true` |
|
||||
| close-icon | 关闭[图标名称](#/zh-CN/icon)或图片链接 | _string_ | `cross` |
|
||||
| close-icon | 关闭图标名称或图片链接,等同于 Icon 组件的 [name 属性](#/zh-CN/icon#props) | _string_ | `cross` |
|
||||
| duration | 动画时长,单位秒,设置为 0 可以禁用动画 | _number \| string_ | `0.3` |
|
||||
| round | 是否显示圆角 | _boolean_ | `true` |
|
||||
| overlay | 是否显示遮罩层 | _boolean_ | `true` |
|
||||
@ -230,11 +230,12 @@ export default {
|
||||
|
||||
### Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
| ---------------- | -------------------- |
|
||||
| default | 自定义面板的展示内容 |
|
||||
| description | 自定义描述文案 |
|
||||
| cancel `v3.0.10` | 自定义取消按钮内容 |
|
||||
| 名称 | 说明 | 参数 |
|
||||
| --- | --- | --- |
|
||||
| default | 自定义面板的展示内容 | - |
|
||||
| description | 自定义描述文案 | - |
|
||||
| cancel `v3.0.10` | 自定义取消按钮内容 | - |
|
||||
| action `v3.4.0` | 自定义选项内容 | _{ action: ActionSheetAction, index: number }_ |
|
||||
|
||||
### 类型定义
|
||||
|
||||
|
@ -4,3 +4,9 @@ import _ActionSheet from './ActionSheet';
|
||||
export const ActionSheet = withInstall(_ActionSheet);
|
||||
export default ActionSheet;
|
||||
export type { ActionSheetProps, ActionSheetAction } from './ActionSheet';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanActionSheet: typeof ActionSheet;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,14 @@ exports[`should allow to custom close icon with closeIcon prop 1`] = `
|
||||
</i>
|
||||
`;
|
||||
|
||||
exports[`should render action slot correctly 1`] = `
|
||||
<button type="button"
|
||||
class="van-action-sheet__item"
|
||||
>
|
||||
name: Option, index: 0
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`should render cancel slot correctly 1`] = `
|
||||
<button type="button"
|
||||
class="van-action-sheet__cancel"
|
||||
|
@ -13,7 +13,7 @@ test('should emit select event after clicking option', async () => {
|
||||
wrapper.find('.van-action-sheet__item').trigger('click');
|
||||
|
||||
await nextTick();
|
||||
expect(wrapper.emitted('select')!.length).toEqual(1);
|
||||
expect(wrapper.emitted('select')).toHaveLength(1);
|
||||
expect(wrapper.emitted('select')![0]).toEqual([
|
||||
{
|
||||
name: 'Option',
|
||||
@ -71,7 +71,7 @@ test('should emit cancel event after clicking cancel button', () => {
|
||||
});
|
||||
|
||||
wrapper.find('.van-action-sheet__cancel').trigger('click');
|
||||
expect(wrapper.emitted('cancel')!.length).toEqual(1);
|
||||
expect(wrapper.emitted('cancel')).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('should render subname correctly', () => {
|
||||
@ -225,7 +225,7 @@ test('should close after clicking option if close-on-click-action prop is true',
|
||||
const option = wrapper.find('.van-action-sheet__item');
|
||||
option.trigger('click');
|
||||
|
||||
expect(wrapper.emitted('update:show')!.length).toEqual(1);
|
||||
expect(wrapper.emitted('update:show')).toHaveLength(1);
|
||||
expect(wrapper.emitted('update:show')![0]).toEqual([false]);
|
||||
});
|
||||
|
||||
@ -261,3 +261,17 @@ test('should allow to control safe-area with safe-area-inset-bottom prop', async
|
||||
'van-safe-area-bottom'
|
||||
);
|
||||
});
|
||||
|
||||
test('should render action slot correctly', () => {
|
||||
const wrapper = mount(ActionSheet, {
|
||||
props: {
|
||||
show: true,
|
||||
actions: [{ name: 'Option' }],
|
||||
},
|
||||
slots: {
|
||||
action: ({ action, index }) => `name: ${action.name}, index: ${index}`,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.find('.van-action-sheet__item').html()).toMatchSnapshot();
|
||||
});
|
||||
|
@ -4,9 +4,9 @@ import {
|
||||
computed,
|
||||
nextTick,
|
||||
reactive,
|
||||
PropType,
|
||||
defineComponent,
|
||||
ExtractPropTypes,
|
||||
type PropType,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
|
||||
// Utils
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { PropType, ref, defineComponent } from 'vue';
|
||||
import { ref, defineComponent, type PropType } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { createNamespace, numericProp } from '../utils';
|
||||
|
@ -9,3 +9,9 @@ export type {
|
||||
AddressEditInstance,
|
||||
AddressEditSearchItem,
|
||||
} from './types';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanAddressEdit: typeof AddressEdit;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { defineComponent, ExtractPropTypes } from 'vue';
|
||||
import { defineComponent, type ExtractPropTypes } from 'vue';
|
||||
|
||||
// Utils
|
||||
import {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { PropType, defineComponent } from 'vue';
|
||||
import { defineComponent, type PropType } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { createNamespace, extend, makeRequiredProp } from '../utils';
|
||||
|
@ -92,7 +92,7 @@
|
||||
right: var(--van-padding-md);
|
||||
color: var(--van-gray-6);
|
||||
font-size: var(--van-address-list-edit-icon-size);
|
||||
transform: translate(0, -50%);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.van-cell {
|
||||
|
@ -5,3 +5,9 @@ export const AddressList = withInstall(_AddressList);
|
||||
export default AddressList;
|
||||
export type { AddressListProps } from './AddressList';
|
||||
export type { AddressListAddress } from './AddressListItem';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanAddressList: typeof AddressList;
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import {
|
||||
computed,
|
||||
reactive,
|
||||
nextTick,
|
||||
PropType,
|
||||
onMounted,
|
||||
defineComponent,
|
||||
ExtractPropTypes,
|
||||
type PropType,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
|
||||
// Utils
|
||||
@ -188,15 +188,15 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
const setValues = () => {
|
||||
let code = state.code || getDefaultCode();
|
||||
const picker = pickerRef.value;
|
||||
const province = getColumnValues('province');
|
||||
const city = getColumnValues('city', code.slice(0, 2));
|
||||
|
||||
if (!picker) {
|
||||
return;
|
||||
}
|
||||
|
||||
let code = state.code || getDefaultCode();
|
||||
const province = getColumnValues('province');
|
||||
const city = getColumnValues('city', code.slice(0, 2));
|
||||
picker.setColumnValues(0, province);
|
||||
picker.setColumnValues(1, city);
|
||||
|
||||
|
@ -5,3 +5,9 @@ export const Area = withInstall(_Area);
|
||||
export default Area;
|
||||
export type { AreaProps } from './Area';
|
||||
export type { AreaList, AreaInstance, AreaColumnOption } from './types';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanArea: typeof Area;
|
||||
}
|
||||
}
|
||||
|
@ -36,14 +36,6 @@ exports[`should render columns-top、columns-bottom slot correctly 1`] = `
|
||||
>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="van-picker__mask"
|
||||
style="background-size: 100% 110px;"
|
||||
>
|
||||
</div>
|
||||
<div class="van-hairline-unset--top-bottom van-picker__frame"
|
||||
style="height: 44px;"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
Bottom
|
||||
</div>
|
||||
@ -130,14 +122,6 @@ exports[`should render two columns when columns-num prop is two 1`] = `
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="van-picker__mask"
|
||||
style="background-size: 100% 110px;"
|
||||
>
|
||||
</div>
|
||||
<div class="van-hairline-unset--top-bottom van-picker__frame"
|
||||
style="height: 44px;"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -116,10 +116,10 @@ test('should render two columns when columns-num prop is two', async () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.findAll('.van-picker-column').length).toEqual(3);
|
||||
expect(wrapper.findAll('.van-picker-column')).toHaveLength(3);
|
||||
|
||||
await wrapper.setProps({ columnsNum: 2 });
|
||||
expect(wrapper.findAll('.van-picker-column').length).toEqual(2);
|
||||
expect(wrapper.findAll('.van-picker-column')).toHaveLength(2);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {
|
||||
computed,
|
||||
PropType,
|
||||
CSSProperties,
|
||||
defineComponent,
|
||||
ExtractPropTypes,
|
||||
type PropType,
|
||||
type CSSProperties,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
import {
|
||||
isDef,
|
||||
|
@ -4,3 +4,9 @@ import _Badge from './Badge';
|
||||
export const Badge = withInstall(_Badge);
|
||||
export default Badge;
|
||||
export type { BadgeProps, BadgePosition } from './Badge';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanBadge: typeof Badge;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {
|
||||
PropType,
|
||||
CSSProperties,
|
||||
defineComponent,
|
||||
ExtractPropTypes,
|
||||
type PropType,
|
||||
type CSSProperties,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
|
||||
// Utils
|
||||
|
@ -126,7 +126,7 @@ app.use(Button);
|
||||
| round | Whether to be round button | _boolean_ | `false` |
|
||||
| square | Whether to be square button | _boolean_ | `false` |
|
||||
| disabled | Whether to disable button | _boolean_ | `false` |
|
||||
| loading | Whether show loading status | _boolean_ | `false` |
|
||||
| loading | Whether to show loading status | _boolean_ | `false` |
|
||||
| loading-text | Loading text | _string_ | - |
|
||||
| loading-type | Loading type, can be set to `spinner` | _string_ | `circular` |
|
||||
| loading-size | Loading icon size | _number \| string_ | `20px` |
|
||||
|
@ -138,7 +138,7 @@ app.use(Button);
|
||||
| size | 尺寸,可选值为 `large` `small` `mini` | _string_ | `normal` |
|
||||
| text | 按钮文字 | _string_ | - |
|
||||
| color | 按钮颜色,支持传入 `linear-gradient` 渐变色 | _string_ | - |
|
||||
| icon | 左侧[图标名称](#/zh-CN/icon)或图片链接 | _string_ | - |
|
||||
| icon | 左侧图标名称或图片链接,等同于 Icon 组件的 [name 属性](#/zh-CN/icon#props) | _string_ | - |
|
||||
| icon-prefix | 图标类名前缀,等同于 Icon 组件的 [class-prefix 属性](#/zh-CN/icon#props) | _string_ | `van-icon` |
|
||||
| icon-position | 图标展示位置,可选值为 `right` | _string_ | `left` |
|
||||
| tag | 按钮根节点的 HTML 标签 | _string_ | `button` |
|
||||
|
@ -10,3 +10,9 @@ export type {
|
||||
ButtonNativeType,
|
||||
ButtonIconPosition,
|
||||
} from './types';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanButton: typeof Button;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ test('should emit click event', () => {
|
||||
const wrapper = mount(Button);
|
||||
|
||||
wrapper.trigger('click');
|
||||
expect(wrapper.emitted('click')!.length).toEqual(1);
|
||||
expect(wrapper.emitted('click')).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('should not emit click event when disabled', () => {
|
||||
|
@ -2,10 +2,10 @@ import {
|
||||
ref,
|
||||
watch,
|
||||
computed,
|
||||
PropType,
|
||||
TeleportProps,
|
||||
defineComponent,
|
||||
ExtractPropTypes,
|
||||
type PropType,
|
||||
type TeleportProps,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
|
||||
// Utils
|
||||
@ -406,7 +406,12 @@ export default defineComponent({
|
||||
);
|
||||
|
||||
if (disabledDay) {
|
||||
select([startDay, getPrevDay(disabledDay)]);
|
||||
const endDay = getPrevDay(disabledDay);
|
||||
if (compareDay(startDay, endDay) === -1) {
|
||||
select([startDay, endDay]);
|
||||
} else {
|
||||
select([date]);
|
||||
}
|
||||
} else {
|
||||
select([startDay, date], true);
|
||||
}
|
||||
|
@ -1,4 +1,9 @@
|
||||
import { computed, CSSProperties, PropType, defineComponent } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
type PropType,
|
||||
type CSSProperties,
|
||||
} from 'vue';
|
||||
import { makeNumberProp, createNamespace, makeRequiredProp } from '../utils';
|
||||
import { bem } from './utils';
|
||||
import type { CalendarDayItem } from './types';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
PropType,
|
||||
defineComponent,
|
||||
ExtractPropTypes,
|
||||
type PropType,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
|
||||
// Utils
|
||||
|
@ -10,3 +10,9 @@ export type {
|
||||
CalendarDayType,
|
||||
CalendarInstance,
|
||||
} from './types';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanCalendar: typeof Calendar;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { defineComponent, ExtractPropTypes } from 'vue';
|
||||
import { defineComponent, type ExtractPropTypes } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { isDef, numericProp, makeStringProp, createNamespace } from '../utils';
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user