diff --git a/.eslintrc.js b/.eslintrc.js index 1205175ff1..1b7c9322a1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -39,6 +39,19 @@ module.exports = { singleline: 3, multiline: 1, }], + '@typescript-eslint/member-delimiter-style': [ + 2, + { + multiline: { + delimiter: 'none', + requireLast: false, + }, + singleline: { + delimiter: 'semi', + requireLast: true, + }, + }, + ], 'vue/html-closing-bracket-spacing': 'error', }, } diff --git a/.storybook/demo.css b/.storybook/demo.css new file mode 100644 index 0000000000..d9bd07e8f9 --- /dev/null +++ b/.storybook/demo.css @@ -0,0 +1,3 @@ +body { + font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif; +} diff --git a/.storybook/preview.js b/.storybook/preview.js index 62f89441ec..7d2bba1855 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,7 +1,8 @@ -import { addDecorator } from '@storybook/html'; -import { createApp } from 'vue'; -import '../src/style/element-ui@2.13.2.css'; +import { addDecorator } from '@storybook/html' +import { createApp } from 'vue' +import '../src/style/element-ui@2.13.2.css' import install from '../packages/element-plus' +import './demo.css' /** * Wraps a story into a Vue Element @@ -11,11 +12,11 @@ import install from '../packages/element-plus' const Wrapper = (template) => { return { data() { - return {}; + return {} }, template, - }; -}; + } +} /** * Custom Addon for previewing ElementPlus component in Vue3 @@ -25,15 +26,15 @@ const Wrapper = (template) => { * @return {HTMLElement} */ function CustomDecorator(content, context) { - const templateOrComponent = content(); + const templateOrComponent = content() const app = typeof templateOrComponent === 'string' ? createApp(Wrapper(templateOrComponent)) : createApp(templateOrComponent) install(app) - const entry = document.createElement('div'); - entry.className = 'element-plus-previewer'; - app.mount(entry); - return entry; + const entry = document.createElement('div') + entry.className = 'element-plus-previewer' + app.mount(entry) + return entry } addDecorator(CustomDecorator); diff --git a/lerna-debug.log b/lerna-debug.log new file mode 100644 index 0000000000..d2d1408b95 --- /dev/null +++ b/lerna-debug.log @@ -0,0 +1,12 @@ +0 silly argv { +0 silly argv _: [ 'add' ], +0 silly argv scope: '@element-plus/avatar', +0 silly argv globs: [], +0 silly argv lernaVersion: '3.22.1', +0 silly argv '$0': '/usr/local/bin/lerna', +0 silly argv pkg: '@element-plus/utils' +0 silly argv } +1 notice cli v3.22.1 +2 verbose rootPath /Users/bytedance/Desktop/code/element-plus +3 error Error: 404 Not Found - GET https://registry.npmjs.org/@element-plus%2futils - Not found +3 error at /Users/bytedance/Desktop/code/element-plus/node_modules/@evocateur/npm-registry-fetch/check-response.js:104:15 diff --git a/packages/avatar/__tests__/avatar.spec.ts b/packages/avatar/__tests__/avatar.spec.ts new file mode 100644 index 0000000000..2ec52a3232 --- /dev/null +++ b/packages/avatar/__tests__/avatar.spec.ts @@ -0,0 +1,15 @@ +import { mount } from '@vue/test-utils' +import Avatar from '../src/index.vue' + +const AXIOM = 'Rem is the best girl' + +describe('Avatar.vue', () => { + test('render test', () => { + const wrapper = mount(Avatar, { + slots: { + default: AXIOM, + }, + }) + expect(wrapper.text()).toEqual(AXIOM) + }) +}) diff --git a/packages/avatar/doc/basic.vue b/packages/avatar/doc/basic.vue new file mode 100644 index 0000000000..c9e50a4c8f --- /dev/null +++ b/packages/avatar/doc/basic.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/packages/avatar/doc/fit-container.vue b/packages/avatar/doc/fit-container.vue new file mode 100644 index 0000000000..14cc592e2b --- /dev/null +++ b/packages/avatar/doc/fit-container.vue @@ -0,0 +1,37 @@ + + + + diff --git a/packages/avatar/doc/index.stories.ts b/packages/avatar/doc/index.stories.ts new file mode 100644 index 0000000000..87a0fddf5b --- /dev/null +++ b/packages/avatar/doc/index.stories.ts @@ -0,0 +1,27 @@ +export default { + title: 'Avatar', +} + +export {default as BasicUsage} from './basic.vue' +export {default as FitAvatarContainer} from './fit-container.vue' + +export const differentAvatarTypes = () => ` +
+
+ +
+
+ +
+
+ user +
+
+` +export const fallbackWhenImageLoadsError = () => ` +
+ + + +
+` diff --git a/packages/avatar/index.ts b/packages/avatar/index.ts new file mode 100644 index 0000000000..3e0a12cefc --- /dev/null +++ b/packages/avatar/index.ts @@ -0,0 +1,5 @@ +import { App } from 'vue' +import Avatar from './src/index.vue' +export default (app: App): void => { + app.component(Avatar.name, Avatar) +} diff --git a/packages/avatar/package.json b/packages/avatar/package.json new file mode 100644 index 0000000000..655ee9e975 --- /dev/null +++ b/packages/avatar/package.json @@ -0,0 +1,15 @@ +{ + "name": "@element-plus/avatar", + "version": "0.0.0", + "main": "dist/index.js", + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.0-rc.1" + }, + "devDependencies": { + "@vue/test-utils": "^2.0.0-beta.0" + }, + "dependencies": { + "@element-plus/utils": "^0.0.0" + } +} diff --git a/packages/avatar/src/index.vue b/packages/avatar/src/index.vue new file mode 100644 index 0000000000..9c90b08b92 --- /dev/null +++ b/packages/avatar/src/index.vue @@ -0,0 +1,85 @@ + + + diff --git a/packages/button/src/index.vue b/packages/button/src/index.vue index 616347ac1c..dd951300e7 100644 --- a/packages/button/src/index.vue +++ b/packages/button/src/index.vue @@ -49,8 +49,10 @@ interface IButtonProps { circle: boolean; } +type EmitFn = (evt: Event) => void + interface IButtonSetups { - _elFormItemSize: string; + _elFormItemSize: number; buttonSize: string; buttonDisabled: boolean; handleClick: EmitFn; diff --git a/packages/element-plus/index.ts b/packages/element-plus/index.ts index f77b615d38..c92b6163bc 100644 --- a/packages/element-plus/index.ts +++ b/packages/element-plus/index.ts @@ -1,4 +1,5 @@ import type { App } from 'vue' +import ElAvatar from '@element-plus/avatar' import ElButton from '@element-plus/button' import ElBadge from '@element-plus/badge' import ElCard from '@element-plus/card' @@ -9,6 +10,7 @@ import ElTimeLine from '@element-plus/time-line' import ElProgress from '@element-plus/progress' export { + ElAvatar, ElLayout, ElButton, ElBadge, @@ -20,6 +22,7 @@ export { } export default function install(app: App): void { + ElAvatar(app) ElButton(app) ElBadge(app) ElCard(app) diff --git a/packages/element-plus/package.json b/packages/element-plus/package.json index 14ebee791a..e0056013f8 100644 --- a/packages/element-plus/package.json +++ b/packages/element-plus/package.json @@ -14,6 +14,7 @@ "url": "https://github.com/element-plus/element-plus/issues" }, "dependencies": { + "@element-plus/avatar": "^0.0.0", "@element-plus/badge": "^0.0.0", "@element-plus/button": "^0.0.0", "@element-plus/layout": "^0.0.0", diff --git a/packages/utils/package.json b/packages/utils/package.json new file mode 100644 index 0000000000..fcc1472402 --- /dev/null +++ b/packages/utils/package.json @@ -0,0 +1,11 @@ +{ + "name": "@element-plus/utils", + "version": "0.0.0", + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.0-rc.1" + }, + "devDependencies": { + "@vue/test-utils": "^2.0.0-beta.0" + } +} diff --git a/packages/utils/types.ts b/packages/utils/types.ts new file mode 100644 index 0000000000..61ba0ef75e --- /dev/null +++ b/packages/utils/types.ts @@ -0,0 +1,16 @@ +type OptionalKeys = { + [K in keyof T]: T extends Record + ? never + : K +}[keyof T] + +type RequiredKeys = Exclude> + +type MonoArgEmitter = (evt: K, arg?: T[K]) => void + +type BiArgEmitter = (evt: K, arg: T[K]) => void + +export type EventEmitter = + MonoArgEmitter> & BiArgEmitter> + +type A = Required<{}>