From 1fc3eae9b30cd34ae07e9f29677ff2de352ec746 Mon Sep 17 00:00:00 2001 From: fikyair Date: Fri, 15 Oct 2021 08:03:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=A0=E5=85=A5modal=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{Buttons => Button}/__tests__/button.tsx | 0 .../{Buttons => Button}/button-doc.mdx | 0 .../{Buttons => Button}/button.stories.tsx | 0 src/components/{Buttons => Button}/button.tsx | 0 src/components/{Buttons => Button}/index.tsx | 0 src/components/{Buttons => Button}/style.scss | 0 src/components/{Buttons => Button}/style.ts | 0 src/components/DropdownButton/index.js | 2 +- src/components/InputDatePicker/datePicker.tsx | 2 +- src/components/InputDatePicker/dateView.tsx | 2 +- .../InputDatePicker/headerTitle.tsx | 2 +- .../InputDatePicker/monthPicker.tsx | 2 +- .../InputDatePicker/monthYearView.tsx | 2 +- src/components/Modal/close.png | Bin 0 -> 368 bytes src/components/Modal/index.tsx | 3 + src/components/Modal/modal-doc.mdx | 63 ++++ src/components/Modal/modal.stories.tsx | 297 ++++++++++++++++++ src/components/Modal/modal.tsx | 243 ++++++++++++++ src/components/Modal/style.scss | 202 ++++++++++++ src/components/Tree/refactor.md | 11 +- src/index.tsx | 5 +- src/styles/_mixin.scss | 177 ++++++----- src/styles/_variables.scss | 28 +- src/styles/index.scss | 7 +- 24 files changed, 960 insertions(+), 88 deletions(-) rename src/components/{Buttons => Button}/__tests__/button.tsx (100%) rename src/components/{Buttons => Button}/button-doc.mdx (100%) rename src/components/{Buttons => Button}/button.stories.tsx (100%) rename src/components/{Buttons => Button}/button.tsx (100%) rename src/components/{Buttons => Button}/index.tsx (100%) rename src/components/{Buttons => Button}/style.scss (100%) rename src/components/{Buttons => Button}/style.ts (100%) create mode 100644 src/components/Modal/close.png create mode 100644 src/components/Modal/index.tsx create mode 100644 src/components/Modal/modal-doc.mdx create mode 100644 src/components/Modal/modal.stories.tsx create mode 100644 src/components/Modal/modal.tsx create mode 100644 src/components/Modal/style.scss diff --git a/src/components/Buttons/__tests__/button.tsx b/src/components/Button/__tests__/button.tsx similarity index 100% rename from src/components/Buttons/__tests__/button.tsx rename to src/components/Button/__tests__/button.tsx diff --git a/src/components/Buttons/button-doc.mdx b/src/components/Button/button-doc.mdx similarity index 100% rename from src/components/Buttons/button-doc.mdx rename to src/components/Button/button-doc.mdx diff --git a/src/components/Buttons/button.stories.tsx b/src/components/Button/button.stories.tsx similarity index 100% rename from src/components/Buttons/button.stories.tsx rename to src/components/Button/button.stories.tsx diff --git a/src/components/Buttons/button.tsx b/src/components/Button/button.tsx similarity index 100% rename from src/components/Buttons/button.tsx rename to src/components/Button/button.tsx diff --git a/src/components/Buttons/index.tsx b/src/components/Button/index.tsx similarity index 100% rename from src/components/Buttons/index.tsx rename to src/components/Button/index.tsx diff --git a/src/components/Buttons/style.scss b/src/components/Button/style.scss similarity index 100% rename from src/components/Buttons/style.scss rename to src/components/Button/style.scss diff --git a/src/components/Buttons/style.ts b/src/components/Button/style.ts similarity index 100% rename from src/components/Buttons/style.ts rename to src/components/Button/style.ts diff --git a/src/components/DropdownButton/index.js b/src/components/DropdownButton/index.js index c1d74136..6e3a64b6 100644 --- a/src/components/DropdownButton/index.js +++ b/src/components/DropdownButton/index.js @@ -2,7 +2,7 @@ import React from "react"; import { Dropdown, useDropdownToggle, useDropdownMenu } from "react-overlays"; import scopedClass from "../../utils/scopedClass"; import classNames from "classnames"; -import { Button } from "../Buttons/button"; +import { Button } from "../Button/button"; const sc = scopedClass("chocolate-dropdown"); diff --git a/src/components/InputDatePicker/datePicker.tsx b/src/components/InputDatePicker/datePicker.tsx index 9c793ca6..77ca1e53 100644 --- a/src/components/InputDatePicker/datePicker.tsx +++ b/src/components/InputDatePicker/datePicker.tsx @@ -6,7 +6,7 @@ import getDate from "date-fns/getDate"; import getMonth from "date-fns/getMonth"; import isSameDay from "date-fns/isSameDay"; import dateFnsIsToday from "date-fns/isToday"; -import { Button } from "../Buttons/button"; +import { Button } from "../Button/button"; import { CalendarProps } from "./calendar"; const sc = scopedClass("chocolate-picker"); diff --git a/src/components/InputDatePicker/dateView.tsx b/src/components/InputDatePicker/dateView.tsx index 2fec9b2a..e92c136c 100644 --- a/src/components/InputDatePicker/dateView.tsx +++ b/src/components/InputDatePicker/dateView.tsx @@ -5,7 +5,7 @@ import React, { } from "react"; import { ViewLayout } from "./viewLayout"; import DatePicker, { CalendarType } from "./datePicker"; -import { Button } from "../Buttons/button"; +import { Button } from "../Button/button"; import Icon from "../Icon/icon"; import HeaderTitle from "./headerTitle"; import { CalendarProps } from "./calendar"; diff --git a/src/components/InputDatePicker/headerTitle.tsx b/src/components/InputDatePicker/headerTitle.tsx index d51a45d8..8ee77200 100644 --- a/src/components/InputDatePicker/headerTitle.tsx +++ b/src/components/InputDatePicker/headerTitle.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Button } from "../Buttons/button"; +import { Button } from "../Button/button"; import format from "date-fns/format"; import { CalendarType } from "./datePicker"; import YearPicker from "./yearPicker"; diff --git a/src/components/InputDatePicker/monthPicker.tsx b/src/components/InputDatePicker/monthPicker.tsx index f6ab6a89..83544aec 100644 --- a/src/components/InputDatePicker/monthPicker.tsx +++ b/src/components/InputDatePicker/monthPicker.tsx @@ -1,6 +1,6 @@ import React from "react"; import scopedClass from "../../utils/scopedClass"; -import { Button } from "../Buttons/button"; +import { Button } from "../Button/button"; import { buildMonths } from "./utils/generator"; import classNames from "classnames"; const sc = scopedClass("chocolate-picker-month"); diff --git a/src/components/InputDatePicker/monthYearView.tsx b/src/components/InputDatePicker/monthYearView.tsx index 29c4f4f3..5c4488ec 100644 --- a/src/components/InputDatePicker/monthYearView.tsx +++ b/src/components/InputDatePicker/monthYearView.tsx @@ -1,7 +1,7 @@ import React, { ChangeEvent, MouseEventHandler } from "react"; import MonthPicker from "./monthPicker"; import ViewLayout from "./viewLayout"; -import { Button } from "../Buttons/button"; +import { Button } from "../Button/button"; import Icon from "../Icon"; import { CalendarType } from "./datePicker"; import HeaderTitle from "./headerTitle"; diff --git a/src/components/Modal/close.png b/src/components/Modal/close.png new file mode 100644 index 0000000000000000000000000000000000000000..6d5d02365203964fdf053cef5c410505c40cd32d GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k&H|6fVg?3oVGw3ym^DWND9BhG z!gEcn;b-1?(z!sMKh`1V4C`; z=z)X9pE8Az1>#Oj>|2?ytvK*P?Jcl0h-)Jzdl4ujq*KLvR3UGU{Nr(BsbV)mP&qwi>_ct6_PSH&PIEBXiKlPZ=!#0* zqU*3+?7}7v^TQctn>ltwx+SW(9lm;@v#+F1nBgAxnZFhD#BV9_rQKvcesUvMPv@N@ zq7(T9{uF+(VG6zewU1q0-eTibZ^cWVE>a) +## Modal 模态框 +对话框组件 + +import { Story, Meta, ArgsTable, Source } from '@storybook/addon-docs/blocks'; +import { Modal } from './modal'; +import dedent from 'ts-dedent'; +; + +### 使用 + + setVisible(false)} + footer={ + <> + + + + } + > +
确认一下
+ + 是否要关闭模态框? + + + ` + } +/> + +### 具体参数 + + +export const Template = (args) => + + +### 组件展示 + + +##### default 类型 + + +{Template.bind({})} + \ No newline at end of file diff --git a/src/components/Modal/modal.stories.tsx b/src/components/Modal/modal.stories.tsx new file mode 100644 index 00000000..14f49ae0 --- /dev/null +++ b/src/components/Modal/modal.stories.tsx @@ -0,0 +1,297 @@ +import React, { useState } from "react"; +import { Story, Meta } from "@storybook/react"; +import Modal, { ModalProps } from "./modal"; +import Button from "../Button"; +import ModalDoc from "./modal-doc.mdx"; + +const BaseModal = (props: ModalProps) => { + const [visible, setVisible] = useState(false); + const [visible2, setVisible2] = useState(false); + const [visible3, setVisible3] = useState(false); + const [visible4, setVisible4] = useState(false); + const [visible5, setVisible5] = useState(false); + const [visible6, setVisible6] = useState(false); + const [visible7, setVisible7] = useState(false); + const [visible8, setVisible8] = useState(false); + const [visible9, setVisible9] = useState(false); + + return ( + <> +
+ setVisible(false)} + footer={ + <> + + + + } + > +
确认一下
+ + 是否要关闭模态框? + +
+ +
+
+ setVisible2(false)} + footer={ + <> + + + + } + > +
确认一下
+ + 是否要关闭模态框? + +
+ +
+
+ setVisible3(false)} + footer={ + <> + + + + } + > +
确认一下
+ + 是否要关闭模态框? + +
+ +
+
+ setVisible4(false)} + footer={ + <> + + + + } + > +
确认一下
+ + 是否要关闭模态框? + +
+ +
+
+ setVisible5(false)} + icon="crow" + footer={ + <> + + + + } + > +
确认一下
+ + 是否要关闭模态框? + +
+ +
+
+ setVisible6(false)} + icon="crow" + theme="primary" + footer={ + <> + + + + } + > +
确认一下
+ + 是否要关闭模态框? + +
+ +
+
+ setVisible7(false)} + onCancel={() => setVisible7(false)} + > +
确认一下
+ + 是否要关闭模态框? + +
+ +
+ +
+ setVisible8(false)} + onCancel={() => setVisible8(false)} + okText="好的" + cancelText="我拒绝" + > +
确认一下
+ + 是否要关闭模态框? + +
+ +
+
+ setVisible9(false)} + onCancel={() => setVisible9(false)} + okText="好的" + cancelText="我拒绝" + width={555} + content="确认一下" + /> + +
+ + ); +}; + +export default { + component: Modal, + title: "Modal", + parameters: { + docs: { + page: ModalDoc, + source: { + type: "code", + }, + }, + }, +} as Meta; + +const _default: Story = (args) => ; + +// 默认 +export const Default = _default.bind({}); + +Default.args = {}; diff --git a/src/components/Modal/modal.tsx b/src/components/Modal/modal.tsx new file mode 100644 index 00000000..0517269a --- /dev/null +++ b/src/components/Modal/modal.tsx @@ -0,0 +1,243 @@ +import React, { FC, useState, KeyboardEvent, ReactNode } from "react"; +import { createPortal } from "react-dom"; +import classNames from "classnames"; +import close from "./close.png"; +import Button from "../Button"; +import Icon from "../Icon"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; +import { ThemeProps } from "../Icon/icon"; + +const prefixCls = "chocolate-modal"; + +export interface ModalProps { + /** + * Modal 框内容,与 children 二选一展示,content 优先 + */ + content?: string | ReactNode; + /** + * 标题 + */ + title: string; + /** + * 是否可见 + */ + visible: boolean; + /** + * 取消事件 + */ + onCancel?: () => void; + /** + * 确认事件 + */ + onOk?: () => void; + /** + * 设置单独的 class + */ + className?: string; + /** + * 底部布局 + */ + footer?: ReactNode; + /** + * 单独设置确认按钮文案 + */ + okText?: string; + /** + * 单独设置取消按钮文案 + */ + cancelText?: string; + /** + * 是否居中展示 + */ + centered?: boolean; + /** + * 是否展示关闭按钮 + */ + closable?: boolean; + /** + * 蒙层可关闭 + */ + maskClosable?: boolean; + /** + * 是否展示蒙层 + */ + showMask?: boolean; + /** + * 添加自定义样式 + */ + style?: CSSStyleSheet; + /** + * 可以单独设置模态框宽度 + */ + width?: number; + /** + * 单独设置模态框层级 + */ + zIndex?: number; + /** + * 设置确认按钮 props + */ + okButtonProps?: {}; + /** + * 设置取消按钮 props + */ + cancelButtonProps?: {}; + /** + * 添加模态框额外外层样式 + */ + wrapperClassName?: string; + /** + * esc 关闭模态框 + */ + escClose?: boolean; + /** + * 添加图标到标题后 + */ + icon?: IconProp; + /** + * 图标主题 + */ + theme?: ThemeProps; +} + +export const Modal: FC = (props) => { + const { + children, + content, + title, + visible, + onCancel, + onOk, + className, + footer, + okText, + cancelText, + centered, + closable, + maskClosable, + showMask, + style, + width, + zIndex, + okButtonProps, + cancelButtonProps, + wrapperClassName, + escClose, + icon, + theme, + ...attr + } = props; + const ESC_KEY_CODE = 27; + const [init, setInit] = useState(false); + + const _onOk = () => { + onOk && onOk(); + }; + const _onCancel = () => { + onCancel && onCancel(); + }; + const onKeyDown = (e: KeyboardEvent) => { + if (!escClose) { + return; + } + if (e.keyCode === ESC_KEY_CODE) { + e.stopPropagation(); + _onCancel(); + } + }; + const maskClickHandle = maskClosable ? { onClick: _onCancel } : {}; + + const defaultFooter = ( + <> + + + + ); + return createPortal( + <> + {showMask && ( +
+ )} +
+
+
+
+ {title} + {icon ? : null} +
+ {closable && ( + + )} +
+
+ {content || children} +
+ {footer ? ( +
{footer}
+ ) : ( +
+ {defaultFooter} +
+ )} +
+
+ , + document.body + ); +}; + +Modal.defaultProps = { + showMask: true, + width: 400, + title: "", + onOk: () => {}, + onCancel: () => {}, + okText: "确定", + cancelText: "取消", + footer: null, + content: "", + maskClosable: true, + centered: false, + closable: true, + zIndex: 999, + okButtonProps: {}, + cancelButtonProps: {}, + escClose: true, +}; + +export default Modal; diff --git a/src/components/Modal/style.scss b/src/components/Modal/style.scss new file mode 100644 index 00000000..2944fb12 --- /dev/null +++ b/src/components/Modal/style.scss @@ -0,0 +1,202 @@ +.chocolate-modal { + pointer-events: auto; + box-shadow: 0 4px 22px 0 rgba(15, 35, 95, 0.12); + background-color: $modal-bg-color; + width: $modal-width; + z-index: $modal-z-index; + transform-origin: bottom center; + outline: none; + position: relative; + margin: 0 auto; + padding: 0; + list-style: none; + transform: scale(0); + top: $modal-offset-top; + margin-bottom: $modal-offset-bottom; + + &.chocolate-modal-open { + pointer-events: auto; + animation: chocolate-fade-in $default-transition forwards; + } + + &.chocolate-modal-open-close { + animation: chocolate-fade-out $default-transition forwards; + pointer-events: none; + } + + &.no-title { + .chocolate-modal-open-header { + border-bottom: 1px solid transparent; + } + } + + &-header { + padding: $modal-header-padding; + border-bottom: 1px solid $border-color; + line-height: 1; + height: $modal-header-height; + position: relative; + + .chocolate-modal-title { + font-size: $modal-title-font-size; + color: $font-color; + margin: 0; + font-weight: 600; + @include ellipsis(1); + } + + .chocolate-modal-close { + position: absolute; + right: 27px; + top: 27px; + cursor: pointer; + color: $modal-close-font-color; + font-size: $modal-close-font-size; + width: 10px; + height: 10px; + + &, + i { + transition: all 0.3s $animate-type; + } + + &:hover { + + &, + i { + color: $primary; + } + } + } + } + + &-content { + padding: $modal-padding; + background-clip: padding-box; + margin: 0 auto; + line-height: 1.5; + word-wrap: break-word; + } + + &-footer { + padding: $modal-footer-padding; + @include flex-center(center); + align-content: center; + } + + .default-footer { + padding: 24px; + display: flex; + justify-content: space-between; + } +} + +.chocolate-modal-wrap { + position: fixed; + overflow: auto; + left: 0; + right: 0; + bottom: 0; + top: 25vh; + z-index: $modal-z-index; + outline: 0; + pointer-events: none; + -webkit-overflow-scrolling: touch; + + &-visible { + pointer-events: none; + } +} + +.chocolate-modal-centered { + text-align: center; + + &::before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; + width: 0; + } + + .chocolate-modal { + display: inline-block; + vertical-align: middle; + top: 0; + text-align: left; + } + + margin-bottom: 0; +} + +.chocolate-modal-mask { + position: fixed; + background-color: $modal-mask-color; + left: 0; + top: 0; + bottom: 0; + right: 0; + width: 100%; + height: 100%; + z-index: $modal-z-index; + pointer-events: none; + transform: scale(0); + + &-show { + pointer-events: auto; + animation: chocolate-mask-fade-in $default-transition forwards; + } + + &-hide { + pointer-events: none; + animation: chocolate-mask-fade-out $default-transition forwards; + } +} + +@include keyframes(chocolate-mask-fade-in) { + from { + opacity: 0; + transform: translate3d(0, 0, 0); + } + + to { + opacity: 1; + transform: scale(1) translate3d(0, 0, 0); + } +} + +@include keyframes(chocolate-mask-fade-out) { + from { + opacity: 1; + transform: translate3d(0, 0, 0); + } + + to { + opacity: 0; + transform: translate3d(0, 0, 0); + } +} + +@include keyframes(chocolate-fade-out) { + from { + opacity: 1; + transform: translate3d(0, 0, 0); + } + + to { + opacity: 0; + transform: translate3d(0, -50px, 0); + } +} + +@include keyframes(chocolate-fade-in) { + from { + opacity: 0; + transform: translate3d(0, -50px, 0); + } + + to { + opacity: 1; + transform: scale(1) translate3d(0, 0, 0); + } +} \ No newline at end of file diff --git a/src/components/Tree/refactor.md b/src/components/Tree/refactor.md index c2f87ed4..12f6b1ff 100644 --- a/src/components/Tree/refactor.md +++ b/src/components/Tree/refactor.md @@ -7,12 +7,14 @@ 指向 这个 DataNode 的父节点,而这个父节点其实就是 DataNode 的上层节点, 所以出现了循环引用。 如何解决这个问题? - - 我首先想到的是去断开这个引用,所以将 parent 的值去做一份深拷贝,但是发现当遇到刚刚新增好的 parent 属性时,会进行不断地递归调用,造成了浏览器卡死,我忽然发现其实不适合做深拷贝的 - - 第二种方式就是对自己的代码进行重构。于是尝试着去阅读 antd 的关于 rc-tree 的源码。发现它是的巧妙之处:用 pos 来保存当前 DataNode 的位置,其实就是 每个 DataNode 的 key 值;用 parentPos 来保存它父节点的 key,而不是一次性把整个父节点都保存。然后在需要对 DataNode 新增 parent 的位置,通过 posEntities[parentPos] 来赋值,posEntities 实体保存了节点所有的 pos 值 + +- 我首先想到的是去断开这个引用,所以将 parent 的值去做一份深拷贝,但是发现当遇到刚刚新增好的 parent 属性时,会进行不断地递归调用,造成了浏览器卡死,我忽然发现其实不适合做深拷贝的 +- 第二种方式就是对自己的代码进行重构。于是尝试着去阅读 antd 的关于 rc-tree 的源码。发现它是的巧妙之处:用 pos 来保存当前 DataNode 的位置,其实就是 每个 DataNode 的 key 值;用 parentPos 来保存它父节点的 key,而不是一次性把整个父节点都保存。然后在需要对 DataNode 新增 parent 的位置,通过 posEntities[parentPos] 来赋值,posEntities 实体保存了节点所有的 pos 值 然后阅读源码的过程中,发现 tree 实现的有问题: - - 没有暴露出 onCheck 接口去让用户去设置 checkbox。第一版的设计仅仅是通过 data,来映射出 tree 节点,然后可以实现 折叠/checkbox/拖拽,但如果作为单独组件导出将不支持回调。最终引入 `onCheck` 来解决 - - 不支持默认选中。引入了 `defaultCheckedKeys` 来解决 + +- 没有暴露出 onCheck 接口去让用户去设置 checkbox。第一版的设计仅仅是通过 data,来映射出 tree 节点,然后可以实现 折叠/checkbox/拖拽,但如果作为单独组件导出将不支持回调。最终引入 `onCheck` 来解决 +- 不支持默认选中。引入了 `defaultCheckedKeys` 来解决 #### 优化 checkbox 选择逻辑 @@ -20,6 +22,7 @@ 操作 tree 的基本依据,所以不得不对这部分进一步重构。 第一版本: + ```js const onCheck = (key: string) => { let target: TreeSource = posEntities.current[key]; diff --git a/src/index.tsx b/src/index.tsx index 68a863fe..0fb80211 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -3,7 +3,7 @@ import { fas } from '@fortawesome/free-solid-svg-icons' library.add(fas) -export { default as Button } from './components/Buttons' +export { default as Button } from './components/Button' export { default as Menu } from './components/Menus' export { default as AutoComplete } from './components/AutoComplete' export { default as Alert } from './components/Alerts' @@ -15,4 +15,5 @@ export { default as Checkbox } from './components/Checkbox' export { default as DatePicker } from './components/InputDatePicker' export { default as Progress } from './components/Progress' export { default as Select } from './components/Select' -export { default as Tab } from './components/Tabs' \ No newline at end of file +export { default as Tab } from './components/Tabs' +export { default as Modal } from './components/Modal' \ No newline at end of file diff --git a/src/styles/_mixin.scss b/src/styles/_mixin.scss index ba329547..b31b5a62 100644 --- a/src/styles/_mixin.scss +++ b/src/styles/_mixin.scss @@ -1,95 +1,132 @@ @mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { - padding: $padding-y $padding-x; - font-size: $font-size; - border-radius: $border-radius; + padding: $padding-y $padding-x; + font-size: $font-size; + border-radius: $border-radius; } @mixin button-style($background, $border, $color, $hover-background: lighten($background, 7.5%), - $hover-border: lighten($border, 10%), - $hover-color: $color, ) { + $hover-border: lighten($border, 10%), + $hover-color: $color, ) { + color: $color; + background: $background; + border-color: $border; + + &:hover { + color: $hover-color; + background: lighten($hover-background, 7.5%); + border-color: lighten($hover-border, 10%); + } + + &:focus, + &.focus { + color: $hover-color; + background: lighten($hover-background, 7.5%); + border-color: lighten($hover-border, 10%); + } + + &:disabled, + &.disabled { color: $color; background: $background; border-color: $border; - - &:hover { - color: $hover-color; - background: lighten($hover-background, 7.5%); - border-color: lighten($hover-border, 10%); - } - - &:focus, - &.focus { - color: $hover-color; - background: lighten($hover-background, 7.5%); - border-color: lighten($hover-border, 10%); - } - - &:disabled, - &.disabled { - color: $color; - background: $background; - border-color: $border; - } + } } @mixin alert-size($padding-y, $padding-x, $font-size, $border-radius) { - padding: $padding-y $padding-x; - font-size: $font-size; - border-radius: $border-radius; + padding: $padding-y $padding-x; + font-size: $font-size; + border-radius: $border-radius; } @mixin alert-style($background, $border, $color) { - background: lighten($background, 40.5%); - border-color: $border; - color: $color; - min-width: max-content; + background: lighten($background, 40.5%); + border-color: $border; + color: $color; + min-width: max-content; } @mixin zoom-animation($direction: 'top', - $scaleStart: scaleY(0), - $scaleEnd: scaleY(1), - $origin: center top, + $scaleStart: scaleY(0), + $scaleEnd: scaleY(1), + $origin: center top, ) { - .zoom-in-#{$direction}-enter { - opacity: 0; - transform: $scaleStart; - } - - .zoom-in-#{$direction}-enter-active { - opacity: 1; - transform: $scaleEnd; - transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms; - transform-origin: $origin - } - - .zoom-in-#{$direction}-exit { - opacity: 1; - } - - .zoom-in-#{$direction}-exit-active { - opacity: 0; - transform: $scaleStart; - transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms; - transform-origin: $origin; - } + .zoom-in-#{$direction}-enter { + opacity: 0; + transform: $scaleStart; + } + + .zoom-in-#{$direction}-enter-active { + opacity: 1; + transform: $scaleEnd; + transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms; + transform-origin: $origin + } + + .zoom-in-#{$direction}-exit { + opacity: 1; + } + + .zoom-in-#{$direction}-exit-active { + opacity: 0; + transform: $scaleStart; + transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms; + transform-origin: $origin; + } } @mixin input-style($padding-y, $padding-x, $font-family, $font-size, $font-weight, - $line-height, $color: rgba($black, .95)) { - padding: $padding-y $padding-x; - font-family: $font-family; - font-size: $font-size; - font-weight: $font-weight; - line-height: $line-height; - color: $color; + $line-height, $color: rgba($black, .95)) { + padding: $padding-y $padding-x; + font-family: $font-family; + font-size: $font-size; + font-weight: $font-weight; + line-height: $line-height; + color: $color; } -@mixin border-right-radius($raduis) { - border-top-right-radius: $raduis; - border-bottom-right-radius: $raduis; +@mixin border-right-radius($radius) { + border-top-right-radius: $radius; + border-bottom-right-radius: $radius; +} + +@mixin border-left-radius($radius) { + border-top-left-radius: $radius; + border-bottom-left-radius: $radius; +} + + +@mixin flex-center($justify: center, $align: center) { + display: flex; + justify-content: $justify; + align-items: $align; +} + +@mixin ellipsis($n: 2) { + overflow: hidden; + text-overflow: ellipsis; + + @if ($n >=2) { + display: -webkit-box; + -webkit-line-clamp: $n; + -webkit-box-orient: vertical; + } + + @if ($n=1) { + white-space: nowrap; + } } -@mixin border-left-radius($raduis) { - border-top-left-radius: $raduis; - border-bottom-left-radius: $raduis; +@mixin keyframes($animationName) { + @-webkit-keyframes #{$animationName} { + @content; + } + @-moz-keyframes #{$animationName} { + @content; + } + @-o-keyframes #{$animationName} { + @content; + } + @keyframes #{$animationName} { + @content; + } } \ No newline at end of file diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss index 67708bc3..994eadd4 100644 --- a/src/styles/_variables.scss +++ b/src/styles/_variables.scss @@ -212,11 +212,11 @@ $btn-font-size: $font-size-base !default; $btn-line-height: $line-height-base !default; //不同大小按钮的 padding 和 font size -$btn-padding-y-sm: .25rem !default; -$btn-padding-x-sm: .5rem !default; +$btn-padding-y-sm: .3rem !default; +$btn-padding-x-sm: .75rem !default; $btn-font-size-sm: $font-size-sm !default; -$btn-padding-y-lg: .5rem !default; +$btn-padding-y-lg: .35rem !default; $btn-padding-x-lg: 1rem !default; $btn-font-size-lg: $font-size-lg !default; @@ -359,4 +359,24 @@ $checkbox-disabled-font-color: fade($g07, 25%); $picker-width: 2.4rem !default; $picker-height: 2.4rem !default; $picker-disabled-color: $g07 !default; -$picker-padding: $padding-small !default; \ No newline at end of file +$picker-padding: $padding-small !default; + +// Modal 模态框 +$modal-offset-top: 100px !default; +$modal-bg-color: $white !default; +$modal-z-index: 999 !default; +$modal-padding: 16px 24px !default; +$modal-header-height: 64px !default; +$modal-footer-padding: 0 0 24px 0 !default; +$modal-title-font-size: $font-size-base !default; +$modal-header-padding: 24px !default; +$modal-close-font-size: 20px !default; +$modal-close-font-color: fade(red, 45%) !default; +$modal-mask-color: rgba($black, .5); +$modal-offset-top: 100px !default; +$modal-offset-bottom: 100px !default; // 超长 modal 距离底部的距离 +$modal-width: 400px !default; +$modal-method-width: 420px !default; +$modal-method-icon-size: 22px !default; +$modal-method-icon-offset: 10px !default; +$modal-header-title-padding: 0 30px !default; \ No newline at end of file diff --git a/src/styles/index.scss b/src/styles/index.scss index 322f8f41..fb9bb15f 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -11,7 +11,7 @@ @import "animation"; // button -@import "../components/Buttons/style"; +@import "../components/Button/style"; // alert @import "../components/Alerts/style"; @@ -50,4 +50,7 @@ @import "../components/InputDatePicker/style"; // DropdownButton -// @import "../components/DropdownButton/style"; \ No newline at end of file +// @import "../components/DropdownButton/style"; + +// Modal +@import "../components/Modal/style"; \ No newline at end of file