Repository: AnnaSearl/anna-remax-ui Branch: master Commit: 1a01e1b28f36 Files: 331 Total size: 1.8 MB Directory structure: gitextract_5muk5lim/ ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .nojekyll ├── .prettierrc.js ├── .umirc.ts ├── CHANGELOG.md ├── README.md ├── babel.config.js ├── build/ │ └── loaders/ │ └── jsxPx2Rem.js ├── components/ │ ├── _util/ │ │ ├── children.ts │ │ ├── index.ts │ │ ├── sync.ts │ │ ├── to.ts │ │ ├── type.ts │ │ └── utils.ts │ ├── action-sheet/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── button/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── card/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── cascade/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── cascade-popup/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── cell/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── checkbox/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── col/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── common/ │ │ └── index.ts │ ├── config-provider/ │ │ └── index.tsx │ ├── date-picker/ │ │ ├── index.tsx │ │ └── style/ │ │ └── index.ts │ ├── dropdown/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── filter/ │ │ ├── filter.tsx │ │ ├── index.ts │ │ ├── item.tsx │ │ └── style/ │ │ ├── filter.scss │ │ ├── index.scss │ │ ├── index.ts │ │ └── item.scss │ ├── form-value/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── grid/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── hooks/ │ │ ├── index.ts │ │ └── useRefs.ts │ ├── icon/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── image-upload/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── images/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── index.ts │ ├── input/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── loading/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── mask/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── one/ │ │ ├── api/ │ │ │ ├── chooseImage/ │ │ │ │ ├── index.ts │ │ │ │ ├── index.web.ts │ │ │ │ └── index.wechat.ts │ │ │ ├── createSelectorQuery/ │ │ │ │ ├── index.ts │ │ │ │ ├── index.web.ts │ │ │ │ └── index.wechat.ts │ │ │ ├── datePicker/ │ │ │ │ ├── index.ts │ │ │ │ ├── index.web.ts │ │ │ │ └── index.wechat.ts │ │ │ ├── hideLoading/ │ │ │ │ ├── index.ts │ │ │ │ ├── index.web.ts │ │ │ │ └── index.wechat.ts │ │ │ ├── index.ts │ │ │ ├── previewImage/ │ │ │ │ ├── index.ts │ │ │ │ ├── index.web.ts │ │ │ │ └── index.wechat.ts │ │ │ ├── showLoading/ │ │ │ │ ├── index.ts │ │ │ │ ├── index.web.ts │ │ │ │ └── index.wechat.ts │ │ │ └── showToast/ │ │ │ ├── index.ts │ │ │ ├── index.web.ts │ │ │ └── index.wechat.ts │ │ ├── base/ │ │ │ ├── checkbox/ │ │ │ │ ├── index.tsx │ │ │ │ ├── index.web.tsx │ │ │ │ └── index.wechat.tsx │ │ │ ├── index.ts │ │ │ ├── picker/ │ │ │ │ ├── index.tsx │ │ │ │ ├── index.web.tsx │ │ │ │ └── index.wechat.tsx │ │ │ └── scroll-view/ │ │ │ ├── index.tsx │ │ │ ├── index.web.tsx │ │ │ └── index.wechat.tsx │ │ └── index.ts │ ├── picker/ │ │ ├── index.tsx │ │ └── style/ │ │ └── index.ts │ ├── popup/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── progress-bar/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── radio/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── rate/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── result/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── row/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── search-bar/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── selector/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── selector-popup/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── skeleton/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── space/ │ │ ├── __test__/ │ │ │ └── index.test.js │ │ ├── index.tsx │ │ ├── s.jsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── spin/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── stepper/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── steps/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── style/ │ │ ├── iconfont/ │ │ │ └── index.scss │ │ ├── index.scss │ │ ├── index.ts │ │ ├── reset/ │ │ │ └── index.scss │ │ └── theme/ │ │ └── index.scss │ ├── swipe-action/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── switch/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── tabs/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── tag/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ ├── textarea/ │ │ ├── index.tsx │ │ └── style/ │ │ ├── index.scss │ │ └── index.ts │ └── web/ │ ├── api/ │ │ ├── chooseImage/ │ │ │ └── index.ts │ │ ├── createSelectorQuery/ │ │ │ └── index.ts │ │ ├── datePicker/ │ │ │ └── index.ts │ │ ├── hideLoading/ │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── previewImage/ │ │ │ └── index.ts │ │ ├── showLoading/ │ │ │ └── index.ts │ │ └── showToast/ │ │ └── index.ts │ ├── base/ │ │ ├── checkbox/ │ │ │ └── index.tsx │ │ ├── image/ │ │ │ └── index.tsx │ │ ├── index.ts │ │ ├── input/ │ │ │ └── index.tsx │ │ ├── picker/ │ │ │ ├── index.tsx │ │ │ └── style/ │ │ │ ├── index.scss │ │ │ └── index.ts │ │ ├── scroll-view/ │ │ │ └── index.tsx │ │ ├── text/ │ │ │ └── index.tsx │ │ ├── textarea/ │ │ │ └── index.tsx │ │ └── view/ │ │ └── index.tsx │ └── index.ts ├── docs/ │ ├── components/ │ │ ├── common/ │ │ │ ├── block/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── common/ │ │ │ │ └── index.ts │ │ │ ├── frame/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── grid/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── grid-item/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ └── index.ts │ │ ├── data-display/ │ │ │ ├── card/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── card.md │ │ │ ├── steps/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── steps.md │ │ │ ├── tabs/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── tabs.md │ │ │ ├── tag/ │ │ │ │ └── index.tsx │ │ │ └── tag.md │ │ ├── data-entry/ │ │ │ ├── cascade/ │ │ │ │ └── index.tsx │ │ │ ├── cascade.md │ │ │ ├── checkbox/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── checkbox.md │ │ │ ├── image-upload/ │ │ │ │ └── index.tsx │ │ │ ├── imageUpload.md │ │ │ ├── input/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── input.md │ │ │ ├── picker/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── picker.md │ │ │ ├── radio/ │ │ │ │ └── index.tsx │ │ │ ├── radio.md │ │ │ ├── rate/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── rate.md │ │ │ ├── search-bar/ │ │ │ │ └── index.tsx │ │ │ ├── searchBar.md │ │ │ ├── selector/ │ │ │ │ └── index.tsx │ │ │ ├── selector.md │ │ │ ├── stepper/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── stepper.md │ │ │ ├── switch/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ └── switch.md │ │ ├── feedback/ │ │ │ ├── action-sheet/ │ │ │ │ └── index.tsx │ │ │ ├── action-sheet.md │ │ │ ├── filter/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── filter.md │ │ │ ├── loading/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── loading.md │ │ │ ├── result/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── result.md │ │ │ ├── skeleton/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ └── skeleton.md │ │ ├── general/ │ │ │ ├── button/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── button.md │ │ │ ├── cell/ │ │ │ │ ├── index.module.scss │ │ │ │ └── index.tsx │ │ │ ├── cell.md │ │ │ ├── icon/ │ │ │ │ └── index.tsx │ │ │ ├── icon.md │ │ │ ├── popup/ │ │ │ │ └── index.tsx │ │ │ └── popup.md │ │ ├── gesture/ │ │ │ ├── swipe-action/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ └── swipe-action.md │ │ ├── layout/ │ │ │ ├── one-dimensional/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── one-dimensional.md │ │ │ ├── space/ │ │ │ │ └── index.tsx │ │ │ ├── space.md │ │ │ ├── two-dimensiona.md │ │ │ └── two-dimensional/ │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ └── mock/ │ │ └── index.ts │ └── index.md ├── gulpfile.js ├── index.js ├── jest.config.js ├── package.json ├── postcss.config.js ├── scripts/ │ ├── copy.ts │ └── getEntries.ts ├── shell/ │ ├── commit.sh │ └── pub.sh ├── site/ │ ├── _demos/ │ │ ├── index/ │ │ │ └── index.html │ │ ├── index-1/ │ │ │ └── index.html │ │ ├── index-10/ │ │ │ └── index.html │ │ ├── index-11/ │ │ │ └── index.html │ │ ├── index-12/ │ │ │ └── index.html │ │ ├── index-13/ │ │ │ └── index.html │ │ ├── index-14/ │ │ │ └── index.html │ │ ├── index-15/ │ │ │ └── index.html │ │ ├── index-16/ │ │ │ └── index.html │ │ ├── index-17/ │ │ │ └── index.html │ │ ├── index-18/ │ │ │ └── index.html │ │ ├── index-19/ │ │ │ └── index.html │ │ ├── index-2/ │ │ │ └── index.html │ │ ├── index-20/ │ │ │ └── index.html │ │ ├── index-21/ │ │ │ └── index.html │ │ ├── index-22/ │ │ │ └── index.html │ │ ├── index-23/ │ │ │ └── index.html │ │ ├── index-24/ │ │ │ └── index.html │ │ ├── index-25/ │ │ │ └── index.html │ │ ├── index-26/ │ │ │ └── index.html │ │ ├── index-27/ │ │ │ └── index.html │ │ ├── index-3/ │ │ │ └── index.html │ │ ├── index-4/ │ │ │ └── index.html │ │ ├── index-5/ │ │ │ └── index.html │ │ ├── index-6/ │ │ │ └── index.html │ │ ├── index-7/ │ │ │ └── index.html │ │ ├── index-8/ │ │ │ └── index.html │ │ └── index-9/ │ │ └── index.html │ ├── index.html │ ├── umi.css │ └── umi.js ├── tests/ │ └── setup.js ├── tsconfig.json ├── tsconfig.webpack.json ├── typings/ │ └── index.d.ts └── webpack.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintignore ================================================ # don't ever lint node_modules node_modules # don't lint site site # don't lint scripts scripts # don't lint build output (make sure it's set to your correct build folder name) cjs /web !components/web esm dist # don't lint gulpfile gulpfile.js webpack.config.js ================================================ FILE: .eslintrc.js ================================================ module.exports = { root: true, parser: '@typescript-eslint/parser', plugins: [ '@typescript-eslint', 'react', 'prettier', ], extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', "plugin:react/recommended", 'prettier/@typescript-eslint', 'plugin:prettier/recommended', "prettier/react", ], env:{ browser: true, node: true, es6: true, jest: true, }, settings: { //自动发现React的版本,从而进行规范react代码 "react": { "pragma": "React", "version": "detect" } }, parserOptions: { //指定ESLint可以解析JSX语法,注:解析JSX并不代表能解析React. "ecmaVersion": 2020, "sourceType": 'module', "ecmaFeatures":{ jsx:true } }, rules: { "@typescript-eslint/explicit-function-return-type": 0, '@typescript-eslint/no-explicit-any': 0, "@typescript-eslint/ban-ts-ignore": 0, "prettier/prettier": ["error", {}], 'react/display-name': 0, } }; ================================================ FILE: .gitignore ================================================ node_modules/ cjs/ web/ !components/web/ esm/ dist/ package-lock.json yarn.lock yarn-error.log .umi/ docs-source/ report.html site/components ================================================ FILE: .nojekyll ================================================ ================================================ FILE: .prettierrc.js ================================================ module.exports = { singleQuote: true, trailingComma: 'all', printWidth: 100, proseWrap: 'never', arrowParens: 'avoid', semi: true, }; ================================================ FILE: .umirc.ts ================================================ import { defineConfig } from 'dumi'; import path from 'path'; process.env.BABEL_ENV = 'dumi'; export default defineConfig({ publicPath: '/anna-remax-ui/', base: '/anna-remax-ui', title: 'Annar', mode: 'site', logo: 'https://smebimage.fuliaoyi.com/Fger7VZclDUaXDJuqg42MlsUqV-w', favicon: 'https://smebimage.fuliaoyi.com/Fger7VZclDUaXDJuqg42MlsUqV-w', navs: [ null, { title: 'Eurus', path: 'https://github.com/AnnaSearl/eurus' }, { title: 'GitHub', path: 'https://github.com/AnnaSearl/annar' }, ], theme: { '@c-primary': '#FF7777', }, exportStatic: {}, outputPath: 'site', sass: { implementation: require('node-sass'), }, extraPostCSSPlugins: [ require('postcss-preset-env')(), require('postcss-plugin-px2rem')({ rootValue: 32, exclude: '@umijs/preset-dumi', }), ], extraBabelPlugins: [ [ 'import', { libraryName: 'anna-remax-ui', libraryDirectory: '/', style: true, }, ], ], alias: { 'anna-remax-ui': path.resolve(__dirname, 'components'), '../one': path.resolve(__dirname, 'components/web/index.ts'), }, chainWebpack(memo, { env, webpack, createCSSRule }) { memo.module .rule('px2rem') .test(/\.tsx$/i) .include.add(path.resolve(__dirname, 'components')) .add(path.resolve(__dirname, 'docs')) .end() .use('px2rem') .loader('./build/loaders/jsxPx2Rem.js') .options({ remUnit: 100, remFixed: 3, }); }, styles: [ ` .icon.icon-link { display: none; } .__dumi-default-navbar{ background-color: #FFEEEE !important; box-shadow: unset !important; } .__dumi-default-navbar-logo{ font-size: 20px !important; padding-left: 52px !important; } .__dumi-default-search-input{ background-color: #FFFFFF !important; } .__dumi-default-layout-hero { background-color: #FFEEEE !important; } .__dumi-default-menu[data-mode='site'] .__dumi-default-menu-list > li > a.active{ background: linear-gradient(to left, rgba(255, 238, 238, 0.5), rgba(248, 250, 255, 0)) !important; } .markdown *:not(pre) code { margin: 0 1px; padding: .2em .4em !important; font-size: .9em; color: rgba(0, 0, 0, 0.85) !important; background: #f2f4f5 !important; border: 1px solid #f0f0f0; border-radius: 3px; font-family: sfmono-regular,Consolas,liberation mono,Menlo,Courier,monospace; } .markdown table td:nth-child(3) { color: #FF5555; font-size: 13px; word-break: break-all; } .markdown table td:nth-child(3) > code { color: #FF5555 !important; background-color: #F6F6F6 !important; font-size: 13px; word-break: break-all; margin-bottom: 6px; } .anna-btn:not(.anna-btn-disabled):hover .anna-btn-mask { box-sizing: border-box; position: absolute; top: -1PX; right: -1PX; bottom: -1PX; left: -1PX; content: ''; background-color: rgba(255, 255, 255, 0.35); border-radius: inherit; pointer-events: none; transition: background-color 0.3s; } `, ], }); ================================================ FILE: CHANGELOG.md ================================================ ## [1.2.6](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.5...v1.2.6) (2020-03-28) ### Features * :sparkles: 新增组件库文档,去除CSSModule, 规范组件css命名规范 ([87ff874](https://github.com/AnnaSearl/anna-remax-ui/commit/87ff8744e02017f40c4f804109086c639b425218)) ## [1.2.5](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.4...v1.2.5) (2020-03-26) ### Bug Fixes * :bug: lock ([4669de2](https://github.com/AnnaSearl/anna-remax-ui/commit/4669de23cd330ccad402739c3f6b4e794005f20c)) * :bug: 修改md文件 ([2c2ae27](https://github.com/AnnaSearl/anna-remax-ui/commit/2c2ae27434ce3e01ac6a0e082cf2b0d3b3fa91c4)) ## [1.2.5](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.4...v1.2.5) (2020-03-26) ### Bug Fixes * :bug: 修改md文件 ([2c2ae27](https://github.com/AnnaSearl/anna-remax-ui/commit/2c2ae27434ce3e01ac6a0e082cf2b0d3b3fa91c4)) ## [1.2.4](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.3...v1.2.4) (2020-03-26) ### Bug Fixes * :bug: lock ([628b280](https://github.com/AnnaSearl/anna-remax-ui/commit/628b280cf0b35c0e2ebb2c57347c72ef2eccb807)) ### Features * :sparkles: 增加对微信小程序的支持 ([4340421](https://github.com/AnnaSearl/anna-remax-ui/commit/4340421e4c17c83f4242342b3ec5e90b75b8cf88)) ## [1.2.4](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.3...v1.2.4) (2020-03-26) ### Features * :sparkles: 增加对微信小程序的支持 ([4340421](https://github.com/AnnaSearl/anna-remax-ui/commit/4340421e4c17c83f4242342b3ec5e90b75b8cf88)) ## [1.2.3](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.1...v1.2.3) (2020-03-26) ### Bug Fixes * :bug: lock ([5ec6bd8](https://github.com/AnnaSearl/anna-remax-ui/commit/5ec6bd807f510ab4ecf4a85b845b1ed3716e22d5)) * :bug: lock ([568c1b2](https://github.com/AnnaSearl/anna-remax-ui/commit/568c1b2fbd6b3eed349386fe341424120ad2b298)) * :bug: 添加md图片 ([eddd242](https://github.com/AnnaSearl/anna-remax-ui/commit/eddd2428b275f50f4531ab401f7c0c1c7cb1de73)) ### Features * :sparkles: 新增Icon组件,修改Cell组件,取消部分组件的cssModule,加入anna样式前缀 ([c3d765f](https://github.com/AnnaSearl/anna-remax-ui/commit/c3d765f0ffaee649097b872b32610015be19c44e)) ## [1.2.3](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.1...v1.2.3) (2020-03-26) ### Bug Fixes * :bug: lock ([568c1b2](https://github.com/AnnaSearl/anna-remax-ui/commit/568c1b2fbd6b3eed349386fe341424120ad2b298)) * :bug: 添加md图片 ([eddd242](https://github.com/AnnaSearl/anna-remax-ui/commit/eddd2428b275f50f4531ab401f7c0c1c7cb1de73)) ### Features * :sparkles: 新增Icon组件,修改Cell组件,取消部分组件的cssModule,加入anna样式前缀 ([c3d765f](https://github.com/AnnaSearl/anna-remax-ui/commit/c3d765f0ffaee649097b872b32610015be19c44e)) # [1.3.0](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.1...v1.3.0) (2020-03-26) ### Bug Fixes * :bug: 添加md图片 ([eddd242](https://github.com/AnnaSearl/anna-remax-ui/commit/eddd2428b275f50f4531ab401f7c0c1c7cb1de73)) ### Features * :sparkles: 新增Icon组件,修改Cell组件,取消部分组件的cssModule,加入anna样式前缀 ([c3d765f](https://github.com/AnnaSearl/anna-remax-ui/commit/c3d765f0ffaee649097b872b32610015be19c44e)) ## [1.2.1](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.0...v1.2.1) (2020-03-25) ### Bug Fixes * :bug: lock ([99e43d7](https://github.com/AnnaSearl/anna-remax-ui/commit/99e43d70c851242dcbb139f1710feae3cf4c2bf2)) * :bug: 添加依赖 ([ff9d648](https://github.com/AnnaSearl/anna-remax-ui/commit/ff9d648845e4b0c327525b346fd1751a1a7e1d5f)) ## [1.2.1](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.2.0...v1.2.1) (2020-03-25) ### Bug Fixes * :bug: 添加依赖 ([ff9d648](https://github.com/AnnaSearl/anna-remax-ui/commit/ff9d648845e4b0c327525b346fd1751a1a7e1d5f)) # [1.2.0](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.1.0...v1.2.0) (2020-03-24) ### Bug Fixes * :bug: lock ([287e1f8](https://github.com/AnnaSearl/anna-remax-ui/commit/287e1f85058834cfd87bb5f319e94e449d5c5788)) ### Features * :sparkles: button新增形状 加载状态 块级属性,loading增加type属性 ([953f151](https://github.com/AnnaSearl/anna-remax-ui/commit/953f15138b4d19e6155928f64e2d3b542c1e04e8)) # [1.2.0](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.1.0...v1.2.0) (2020-03-24) ### Features * :sparkles: button新增形状 加载状态 块级属性,loading增加type属性 ([953f151](https://github.com/AnnaSearl/anna-remax-ui/commit/953f15138b4d19e6155928f64e2d3b542c1e04e8)) # [1.2.0](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.1.0...v1.2.0) (2020-03-24) ### Features * :sparkles: button新增形状 加载状态 块级属性,loading增加type属性 ([953f151](https://github.com/AnnaSearl/anna-remax-ui/commit/953f15138b4d19e6155928f64e2d3b542c1e04e8)) # [1.2.0](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.1.0...v1.2.0) (2020-03-24) ### Features * :sparkles: button新增形状 加载状态 块级属性,loading增加type属性 ([953f151](https://github.com/AnnaSearl/anna-remax-ui/commit/953f15138b4d19e6155928f64e2d3b542c1e04e8)) # [1.1.0](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.0.19...v1.1.0) (2020-03-23) ### Bug Fixes * :bug: 修改shell/pub ([7c97706](https://github.com/AnnaSearl/anna-remax-ui/commit/7c977067e728887eadd5507b39e12263ec38d972)) * :bug: 修改shell/pub ([a13d61b](https://github.com/AnnaSearl/anna-remax-ui/commit/a13d61b091a848889ea5554bd72b82f2cb83924c)) # [1.1.0](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.0.19...v1.1.0) (2020-03-23) ### Bug Fixes * :bug: 修改shell/pub ([a13d61b](https://github.com/AnnaSearl/anna-remax-ui/commit/a13d61b091a848889ea5554bd72b82f2cb83924c)) # [1.1.0](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.0.19...v1.1.0) (2020-03-23) ### Bug Fixes * :bug: 修改shell/pub ([a13d61b](https://github.com/AnnaSearl/anna-remax-ui/commit/a13d61b091a848889ea5554bd72b82f2cb83924c)) ## [1.0.19](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.0.18...v1.0.19) (2020-03-23) ### Bug Fixes * :bug: cancel ignore pakage-lock.json ([cc08adc](https://github.com/AnnaSearl/anna-remax-ui/commit/cc08adc6ff22efbe511c99885355ac86a8074a1f)) * :bug: ignore pakage-lock.json ([84073f4](https://github.com/AnnaSearl/anna-remax-ui/commit/84073f4144fbed61996ba5fbf99f261b06d1d449)) ## [1.0.19](https://github.com/AnnaSearl/anna-remax-ui/compare/v1.0.18...v1.0.19) (2020-03-23) ### Bug Fixes * :bug: ignore pakage-lock.json ([84073f4](https://github.com/AnnaSearl/anna-remax-ui/commit/84073f4144fbed61996ba5fbf99f261b06d1d449)) ## 1.0.18 (2020-03-23) ### Bug Fixes * :bug: ignore pakage-lock.json ([fc33525](https://github.com/AnnaSearl/anna-remax-ui/commit/fc33525693c40c5664a196f5c8f6d9a60d11cff9)) * :bug: ignore pakage-lock.json ([ab11d02](https://github.com/AnnaSearl/anna-remax-ui/commit/ab11d027b25975cc7fb0629675901ca041e2038a)) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) ## 1.0.18 (2020-03-23) ### Bug Fixes * :bug: ignore pakage-lock.json ([ab11d02](https://github.com/AnnaSearl/anna-remax-ui/commit/ab11d027b25975cc7fb0629675901ca041e2038a)) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) # 1.1.0 (2020-03-23) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) ## 1.0.18 (2020-03-23) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) ## 1.0.18 (2020-03-23) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) ## 1.0.18 (2020-03-23) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) ## 1.0.18 (2020-03-23) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) ## 1.0.18 (2020-03-23) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) ## 1.0.18 (2020-03-23) ### Features * :sparkles: 新增commit规范和解决Path变量类型未声明的问题 ([64abdbc](https://github.com/AnnaSearl/anna-remax-ui/commit/64abdbc7142e85dc390bf61f8bdee8ad2fc355d8)) ================================================ FILE: README.md ================================================

Anna Remax UI

优雅、简洁的 Remax 组件库
## :tada: Anna 2.0 `anna-remax-ui` 现已升级到 2.0,并更名为 `annar` ,我们推荐您使用 `annar` 而不是 `anna-remax-ui`,我们将一直维护 `annar` 并 添加新的特性。 👉 [查看 Anna 2.0,发现 Anna 的最新组件及特性!](https://github.com/AnnaSearl/annar) ## 💫 特性 - 基于 `Remax` 开发 UI 组件 - 支持`微信` `支付宝` `钉钉` 小程序多端适配运行 - 支持 Web 开发 - 支持按需引入 - 支持 TypeScript ## 📦 安装 ```bash npm install anna-remax-ui ``` ```bash yarn add anna-remax-ui ``` ## ⚒ 使用 > :warning: `anna-remax-ui` v1.6.0 为破坏性的更新,不再兼容以前的版本。 #### 小程序 ```jsx import { Button } from 'anna-remax-ui'; const App = () => ( <> ); ``` 在 `app.js` 中引入样式: ```jsx import 'anna-remax-ui/dist/anna.css'; ``` #### Web 使用 Web 组件开发需要依赖 `remax/one` ```bash npm install remax/one ``` ```jsx import { Button } from 'anna-remax-ui/web'; const App = () => ( <> ); ``` 引入样式: ```jsx import 'anna-remax-ui/dist/anna.css'; ``` ## 🥡 按需加载 `anna-remax-ui` 的 JS 部分默认支持 tree shaking。 #### 小程序 CSS 部分需要在 `app.js` 中手动引入 ```jsx import 'anna-remax-ui/esm/button/style/css'; // 如果你使用 sass,也可以这样引入 import 'anna-remax-ui/esm/button/style'; ``` #### Web 通过配置 `babel-plugin-import` 进行 CSS 的按需加载 ## 🧑🏻‍💻 本地开发 ```bash $ git clone git@github.com:AnnaSearl/anna-remax-ui.git $ cd anna-remax-ui $ npm install $ npm start ``` ## 🤝 参与共建 如果你有任何问题,可以提交 issue 给我们,我们也非常欢迎你加入 `Anna Remax UI` 的建设,向我们提交 PR。 Anna Remax UI 维护 `master` 和 `feature` 两个分支,如果您是修复 bug,请提交到 `master`;如果您要添加新的功能,请提交到 `feature`。 #### Pull Request 规范 1. 我们建议保持你的 PR 足够小。保证一个 PR 只解决一个问题或只添加一个功能 2. 在 PR 中请添加合适的描述,并关联相关的 Issue 3. 在 Pull Request 前,请同步主仓库的最新代码 #### 常用命令 1. `npm start` 在本地运行 Anna Remax UI 的网站 2. `npm run lint` 检查代码风格 3. `npm run build` 编译 TypeScript 代码到 esm、web 以及 dist 目录 ## 🌰 示例 [Examples for Anna](https://github.com/AnnaSearl/examples-anna-remax-ui) ## 🍭 体验 > :vertical_traffic_light: 体验小程序上的组件版本较低,若想查看 `Anna` 的最新组件及特性,请前往 [官方文档](https://annasearl.github.io/anna-remax-ui/) ## 🍻 钉钉交流群 ================================================ FILE: babel.config.js ================================================ const presets = ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript']; const plugins = [ '@babel/plugin-transform-modules-commonjs', '@babel/plugin-proposal-class-properties', '@babel/plugin-transform-runtime', ]; module.exports = api => { if (api.env('dumi')) { return { presets: ['@babel/preset-env'], }; } if (api.env('esm')) { return { presets: [ '@babel/preset-react', '@babel/preset-typescript', [ '@babel/preset-env', { modules: false, }, ], ], plugins: [ '@babel/plugin-proposal-class-properties', [ '@babel/plugin-transform-runtime', { useESModules: true, }, ], ], }; } if (api.env('web')) { return { presets, plugins: ['@babel/plugin-proposal-class-properties', '@babel/plugin-transform-runtime'], }; } if (api.env('test')) { return { presets: [ '@babel/preset-react', '@babel/preset-typescript', [ '@babel/preset-env', { targets: { node: 'current', }, }, ], ], plugins, }; } // default return { presets: ['@babel/preset-env'], }; }; ================================================ FILE: build/loaders/jsxPx2Rem.js ================================================ const loaderUtils = require('loader-utils'); // 默认参数 const defaultopts = { remUnit: 32, // rem unit value (default: 100) remFixed: 2, // rem value precision (default: 2) }; // 获取webpack配置好的参数 const opts = loaderUtils.getOptions(this); // 将参数组合 const config = Object.assign({}, defaultopts, opts); const ZPXRegExp = /\b(\d+(\.\d+)?)px\b/; module.exports = function (source) { const pxGlobalRegExp = new RegExp(ZPXRegExp.source, 'g'); if (this.cacheable) { this.cacheable(); } // 先test下有没有符合的如果有再进行替换 if (pxGlobalRegExp.test(source)) { return source.replace(pxGlobalRegExp, ($0, $1) => { let val = $1 / config.remUnit; // 精确到几位 val = parseFloat(val.toFixed(config.remFixed)); return val === 0 ? val : val + 'rem'; }); } else { return source; } }; ================================================ FILE: components/_util/children.ts ================================================ // import React from 'react'; // import { isFragment } from 'react-is'; // export const toArray = (children: React.ReactNode): React.ReactElement[] => { // let ret: React.ReactElement[] = []; // React.Children.forEach(children, (child: any) => { // if (child === undefined || child === null) { // return; // } // if (Array.isArray(child)) { // ret = ret.concat(toArray(child)); // } else if (isFragment(child) && child.props) { // ret = ret.concat(toArray(child.props.children)); // } else { // ret.push(child); // } // }); // return ret; // }; ================================================ FILE: components/_util/index.ts ================================================ import to from './to'; import sync from './sync'; export * from './type'; export * from './utils'; export { sync, to }; ================================================ FILE: components/_util/sync.ts ================================================ const sync = (fn: Function, ...args: any[]): Promise => { return new Promise((resolve, reject) => { const obj = { ...args[0] }; const success = obj.success; obj.success = function (...params: any[]) { success && success.apply(this, ...params); const r = params.length > 1 ? params : params[0]; resolve(r); }; const fail = obj.fail; obj.fail = function (...params: any[]) { fail && fail.apply(this, ...params); const r = params.length > 1 ? params : params[0]; reject(r); }; fn(obj); }); }; export default sync; ================================================ FILE: components/_util/to.ts ================================================ const to = (promise: Promise): Promise => { // eslint-disable-next-line no-prototype-builtins if (!promise || !Promise.prototype.isPrototypeOf(promise)) { return new Promise((resolve, reject) => { reject(new Error('requires promises as the param')); }).catch(err => { return [err, null]; }); } return promise .then(function (...args) { return [null, ...args]; }) .catch(err => { return [err]; }); }; export default to; ================================================ FILE: components/_util/type.ts ================================================ export type Omit = Pick>; // https://stackoverflow.com/questions/46176165/ways-to-get-string-literal-type-of-array-values-without-enum-overhead export const tuple = (...args: T) => args; export const tupleNum = (...args: T) => args; ================================================ FILE: components/_util/utils.ts ================================================ export interface Obj { [key: string]: any; } export const guid = () => { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = (Math.random() * 16) | 0; const v = c == 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); }; // 如果你想禁用第一次首先执行的话,传递{leading: false},还有如果你想禁用最后一次执行的话,传递{trailing: false}。 // 默认是 第一次首先执行并且最后一次会执行,相当于 {leading: true, trailing: true} export const throttle = (func: any, wait: any, options?: any) => { let previous = 0; let timeout: any = null; let context: any; let args: any; if (!options) options = {}; const later = function () { previous = options.leading === false ? 0 : new Date().getTime(); timeout = null; func.apply(context, args); if (!timeout) context = args = null; }; const throttled = function (this: any) { const now = new Date().getTime(); if (!previous && options.leading === false) previous = now; const remaining = wait - (now - previous); context = this; // eslint-disable-next-line prefer-rest-params args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } }; return throttled; }; export const mergeStyle = (target: Obj | undefined, style: Obj) => { const newTarget = target ? { ...target } : {}; for (const key in style) { if (Object.prototype.hasOwnProperty.call(style, key)) { const element = style[key]; if (element || element === 0) { newTarget[key] = element; } } } return newTarget; }; export const twoDimensional = ( data: any[], columns: number, span?: number | number[], standard = 24, ): [any[], any[]] => { const two: any[] = []; const spanTwo: any[] = []; const colSpan = standard / columns; if (!Array.isArray(data)) { return [two, spanTwo]; } let spanArray = []; if (span) { spanArray = new Array(data.length).fill(colSpan); if (typeof span === 'number') { if (span > 0) { spanArray[0] = span; } if (span < 0) { spanArray[data.length - 1] = Math.abs(span); } } if (Array.isArray(span)) { spanArray = span.concat(spanArray.slice(span.length)); } let prev = 0; let rowIndex = 0; for (let i = 0; i < spanArray.length; i++) { const item = spanArray[i]; const row = [data[i]]; const spanRow = [item]; if (item >= 24) { rowIndex = two.push(row); spanTwo.push(spanRow); } else { if (24 - prev >= item) { two[rowIndex] ? (two[rowIndex] = two[rowIndex].concat(data[i])) : (rowIndex = two.push(row) - 1); spanTwo[rowIndex] ? (spanTwo[rowIndex] = spanTwo[rowIndex].concat(item)) : (rowIndex = spanTwo.push(spanRow) - 1); prev += item; } else { rowIndex = two.push(row) - 1; spanTwo.push(spanRow); prev = item; } } } return [two, spanTwo]; } const rowsLength = Math.ceil(data.length / columns); const oneDimensional = data.concat([]); let index = 0; for (let i = 0; i < rowsLength; i++) { const row = oneDimensional.slice(index, (index += columns)); two.push(row); spanTwo.push(new Array(row.length).fill(colSpan)); } return [two, spanTwo]; }; export const flat = (arr: any[]): any[] => { if (!Array.isArray(arr)) { return []; } return arr.reduce((prev, curr) => { if (Array.isArray(curr)) { return prev.concat(flat(curr)); } return prev.concat(curr); }, []); }; export const isObjectValueEqual = (a: Obj, b: Obj) => { //取对象a和b的属性名 const aProps = Object.getOwnPropertyNames(a); const bProps = Object.getOwnPropertyNames(b); //判断属性名的length是否一致 if (aProps.length != bProps.length) { return false; } //循环取出属性名,再判断属性值是否一致 for (let i = 0; i < aProps.length; i++) { const propName = aProps[i]; if (a[propName] !== b[propName]) { return false; } } return true; }; export const isArrayValueEqual = (a: any[], b: any[]) => { if (!Array.isArray(a) || !Array.isArray(b)) { return false; } //判断array的length是否一致 if (a.length != b.length) { return false; } let isEqual = true; for (let i = 0; i < a.length; i += 1) { if (typeof a[i] === 'object' && typeof b[i] === 'object') { !isObjectValueEqual(a[i], b[i]) && (isEqual = false); } else { a[i] !== b[i] && (isEqual = false); } } return isEqual; }; export const deepClone = function (data: any): any { let cloneData: any = null; if (Array.isArray(data)) { cloneData = []; for (let i = 0; i < data.length; i += 1) { const item = data[i]; cloneData[i] = deepClone(item); } } else if (typeof data === 'object' && data !== null) { cloneData = {}; Object.keys(data).forEach(key => { const item = data[key]; cloneData[key] = deepClone(item); }); } else { cloneData = data; } return cloneData; }; ================================================ FILE: components/action-sheet/index.tsx ================================================ import React from 'react'; import { View } from 'remax/one'; import classNames from 'classnames'; import Popup from '../popup'; import Icon from '../icon'; import { getPrefixCls } from '../common'; const prefixCls = getPrefixCls('action-sheet'); export interface ActionSheetActionGridProps { value?: string | number; name?: React.ReactNode; icon?: string; disabled?: boolean; } export interface ActionSheetActionDefaultProps { value?: string | number; text?: React.ReactNode | ActionSheetActionGridProps[]; type?: string; mode?: string; disabled?: boolean; } export type ActionSheetAction = ActionSheetActionDefaultProps | ActionSheetActionGridProps; export interface ActionSheetProps { open?: boolean; title?: React.ReactNode; actions?: ActionSheetActionDefaultProps[]; cancelText?: React.ReactNode; cover?: boolean; children?: React.ReactNode; maskClosable?: boolean; onCancel?: (e?: any) => void; onChange?: (a: ActionSheetAction, g?: ActionSheetActionDefaultProps, e?: any) => void; } const ActionSheet = (props: ActionSheetProps) => { const { open, title, actions, cancelText = 'Cancel', cover, maskClosable = true, onCancel, onChange, } = props; const handleCancel = (e: any) => { onCancel?.(e); }; const handleChange = ( action: ActionSheetAction, grid?: ActionSheetActionDefaultProps, e?: any, ) => { onChange?.(action, grid, e); }; const handleCloseMask = () => { maskClosable && onCancel?.(); }; const renderAction = (action: ActionSheetActionDefaultProps) => ( handleChange(action, undefined, e)} > {action.text} ); const renderGrid = (action: ActionSheetActionDefaultProps) => ( {(action.text as ActionSheetActionGridProps[])?.map((item: ActionSheetActionGridProps) => ( handleChange(item, action, e)} > {item.icon ? ( ) : ( item.name )} {item.name} ))} ); return ( {title ? ( {title} ) : null} {actions?.map(action => action.mode === 'grid' ? renderGrid(action) : renderAction(action), )} {cancelText} ); }; export default ActionSheet; ================================================ FILE: components/action-sheet/style/index.scss ================================================ @import '../../style/theme/index'; $action-sheet-prefix-cls: #{$anna-prefix}-action-sheet; .#{$action-sheet-prefix-cls} { position: relative; overflow: hidden; font-size: 28px; color: rgba(0, 0, 0, 0.9); font-weight: 400; text-align: center; &-container{ margin: 0 24px 16px; border-radius: 32px; overflow: hidden; } &-cover{ margin: 0; border-radius: 0; } &-menu { padding-bottom: 16px; background-color: $light-5; } &-action { position: relative; height: 112px; line-height: 112px; background-color: $light-base; font-size: 34px; cursor: pointer; user-select: none; &:active { background-color: $active-bg-1; } &:not(:last-child):before{ box-sizing: border-box; position: absolute; left: 0; right: 0; bottom: 0; content: ''; height: 1PX; background-color: rgba(0, 0, 0, 0.1); transform: scale(1, 0.5); pointer-events: none; // 这样伪类元素可以点击穿透, 也就是能看到, 但是不触发任何默认事件(click等); } &-destructive{ color: $danger-color; } } &-grid { position: relative; background-color: $light-base; &:not(:last-child):before{ box-sizing: border-box; position: absolute; left: 0; right: 0; bottom: 0; content: ''; height: 1PX; background-color: rgba(0, 0, 0, 0.1); transform: scale(1, 0.5); pointer-events: none; // 这样伪类元素可以点击穿透, 也就是能看到, 但是不触发任何默认事件(click等); } &-wrapper { display: flex; padding: 32px 24px; overflow: scroll; &::-webkit-scrollbar{ display: none; } } &-item { box-sizing: border-box; position: relative; width: 106px; max-width: 106px; margin-right: 36px; cursor: pointer; user-select: none; &:nth-last-child(1){ margin-right: 0; } &:nth-last-child(1) { &::before { box-sizing: border-box; position: absolute; content: ''; top: 0; bottom: 0; right: -24px; width: 24px; } } &:active &-icon{ background-color: rgba(0, 0, 0, 0.5); } &-icon { display: flex; justify-content: center; align-items: center; height: 106px; width: 106px; border-radius: 16px; background-color: $light-4; overflow: hidden; font-weight: 500; font-size: 32px; } &-name { margin-top: 16px; font-size: 24px; word-break: keep-all; } } } &-title { font-size: 24px; color: rgba(0, 0, 0, 0.5); } &-cancel { height: 112px; line-height: 112px; background-color: $light-base; cursor: pointer; font-size: 34px; user-select: none; &:active { background-color: $active-bg-2; } } } ================================================ FILE: components/action-sheet/style/index.ts ================================================ import '../../style/index.scss'; import './index.scss'; ================================================ FILE: components/button/index.tsx ================================================ import * as React from 'react'; import { View, Text, Button } from 'remax/one'; import classNames from 'classnames'; import { tuple } from '../_util'; import Loading from '../loading'; import Icon from '../icon'; import { getPrefixCls } from '../common'; const prefixCls = getPrefixCls('btn'); const ButtonTypes = tuple('default', 'primary'); export type ButtonType = typeof ButtonTypes[number]; export interface ButtonProps { type?: ButtonType; size?: string; className?: string; style?: React.CSSProperties; children?: React.ReactNode; disabled?: boolean; danger?: boolean; shape?: string; block?: boolean; float?: boolean | string; loading?: boolean; loadingText?: string; plain?: boolean; hairline?: boolean; look?: string; color?: string; icon?: string | React.ReactNode; ghost?: boolean; onTap?: (e: any) => void; [restProps: string]: any; } const AButton = (props: ButtonProps): React.ReactElement => { const { type, size, className, style, children, onTap, disabled, danger, shape, block, float, loading, loadingText, plain, hairline, look, color, icon, ghost, ...restProps } = props; const handleTap = (e: any) => { if (disabled) { return; } if (loading) { return; } onTap?.(e); }; const renderIcon = (childrenElement: any) => { let iconSize = '32px'; if (size === 'small') { iconSize = '28px'; } if (size === 'large') { iconSize = '36px'; } let iconColor = '#1890FF'; if (type === 'primary') { iconColor = '#FDFFFD'; } if (plain) { if (type === 'primary') { iconColor = '#1890FF'; } if (color) { iconColor = color; } } if (typeof icon === 'string') { return ( ); } if (React.isValidElement(icon)) { return { ...icon, props: { ...icon?.props, style: { verticalAlign: '-0.05em', marginRight: childrenElement ? '6px' : undefined, ...icon?.props?.style, }, }, }; } return null; }; const classes = classNames(prefixCls, className, { [`${prefixCls}-${shape}`]: shape, [`${prefixCls}-${size}`]: size, [`${prefixCls}-primary`]: type === 'primary', [`${prefixCls}-ghost`]: ghost, [`${prefixCls}-plain`]: plain, [`${prefixCls}-hairline`]: hairline, [`${prefixCls}-block`]: block, [`${prefixCls}-float`]: float, [`${prefixCls}-float-${float}`]: float, [`${prefixCls}-danger-default`]: danger, [`${prefixCls}-danger`]: type === 'primary' && danger, [`${prefixCls}-look-${look}`]: look, [`${prefixCls}-loading`]: loading, [`${prefixCls}-disabled`]: disabled || loading, }); const childrenElement = loading && loadingText ? loadingText : children; const iconElement = renderIcon(childrenElement); return ( ); }; export default AButton; ================================================ FILE: components/button/style/index.scss ================================================ @import '../../style/theme/index'; $button-prefix-cls: #{$anna-prefix}-btn; $large-height: 80px; .#{$button-prefix-cls} { position: relative; box-sizing: border-box; display: inline-block; padding: 0 32px; background-color: $btn-default-bg; height: 64px; line-height: 60px; border: 1PX solid $btn-default-bg; border-radius: 64px; color: $brand-color; font-weight: 500; font-size: 28px; text-align: center; white-space: nowrap; user-select: none; touch-action: manipulation; -webkit-appearance: none; transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); // 移除浏览器默认样式 margin: 0; outline: 0; cursor: pointer; // 覆盖微信默认的