@yqg/easy-ui
Advanced tools
| <svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <g clip-path="url(#clip0_253_6708)"> | ||
| <path d="M5.64302 3.8234L2.71099 0.891369C2.67603 0.856492 2.63152 0.832751 2.58308 0.82314C2.53464 0.813529 2.48444 0.818479 2.43881 0.837366C2.39318 0.856252 2.35417 0.888229 2.32669 0.929263C2.29922 0.970297 2.28451 1.01855 2.28442 1.06793V6.93199C2.28435 6.98144 2.29895 7.0298 2.32637 7.07096C2.35378 7.11211 2.39279 7.14421 2.43845 7.16319C2.48411 7.18218 2.53438 7.18719 2.58289 7.17761C2.6314 7.16802 2.67598 7.14426 2.71099 7.10934L5.64302 4.17653C5.66626 4.15337 5.6847 4.12585 5.69729 4.09556C5.70987 4.06526 5.71635 4.03277 5.71635 3.99996C5.71635 3.96715 5.70987 3.93467 5.69729 3.90437C5.6847 3.87407 5.66626 3.84655 5.64302 3.8234Z" fill="#999999"/> | ||
| </g> | ||
| <defs> | ||
| <clipPath id="clip0_253_6708"> | ||
| <rect width="8" height="8" fill="white"/> | ||
| </clipPath> | ||
| </defs> | ||
| </svg> |
| <svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <g clip-path="url(#clip0_253_6702)"> | ||
| <path d="M5.64302 3.8234L2.71099 0.891369C2.67603 0.856492 2.63152 0.832751 2.58308 0.82314C2.53464 0.813529 2.48444 0.818479 2.43881 0.837366C2.39318 0.856252 2.35417 0.888229 2.32669 0.929263C2.29922 0.970297 2.28451 1.01855 2.28442 1.06793V6.93199C2.28435 6.98144 2.29895 7.0298 2.32637 7.07096C2.35378 7.11211 2.39279 7.14421 2.43845 7.16319C2.48411 7.18218 2.53438 7.18719 2.58289 7.17761C2.6314 7.16802 2.67598 7.14426 2.71099 7.10934L5.64302 4.17653C5.66626 4.15337 5.6847 4.12585 5.69729 4.09556C5.70987 4.06526 5.71635 4.03277 5.71635 3.99996C5.71635 3.96715 5.70987 3.93467 5.69729 3.90437C5.6847 3.87407 5.66626 3.84655 5.64302 3.8234Z" fill="#3FCA58"/> | ||
| </g> | ||
| <defs> | ||
| <clipPath id="clip0_253_6702"> | ||
| <rect width="8" height="8" fill="white"/> | ||
| </clipPath> | ||
| </defs> | ||
| </svg> |
| <svg width="100" height="76" viewBox="0 0 100 76" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <g style="mix-blend-mode:screen" filter="url(#filter0_f_1407_1673)"> | ||
| <path d="M4 66C13.3754 48.5248 27.864 12.8596 29.0802 10H97L72.68 66H4Z" fill="url(#paint0_linear_1407_1673)" fill-opacity="0.4"/> | ||
| </g> | ||
| <defs> | ||
| <filter id="filter0_f_1407_1673" x="-6" y="0" width="113" height="76" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> | ||
| <feFlood flood-opacity="0" result="BackgroundImageFix"/> | ||
| <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/> | ||
| <feGaussianBlur stdDeviation="5" result="effect1_foregroundBlur_1407_1673"/> | ||
| </filter> | ||
| <linearGradient id="paint0_linear_1407_1673" x1="-0.566305" y1="35.2903" x2="79.8604" y2="90.4695" gradientUnits="userSpaceOnUse"> | ||
| <stop offset="0.114373" stop-color="white" stop-opacity="0"/> | ||
| <stop offset="0.589034" stop-color="white"/> | ||
| <stop offset="0.73979" stop-color="white" stop-opacity="0"/> | ||
| </linearGradient> | ||
| </defs> | ||
| </svg> |
| import React from 'react'; | ||
| import { ButtonV2Props } from './PropsType'; | ||
| import './style/index.less'; | ||
| declare const ButtonV2: React.FC<ButtonV2Props>; | ||
| export default ButtonV2; |
| import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
| import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
| import clsx from 'clsx'; | ||
| import React, { useEffect, useRef, useState } from 'react'; | ||
| import { createNamespace } from "../utils"; | ||
| import useDebounce from "../utils/hooks/useDebounce"; | ||
| import BlackIcon from "./img/black-icon.svg"; | ||
| import GreenIcon from "./img/green-icon.svg"; | ||
| import LightIcon from "./img/light.svg"; | ||
| import "./style/index.less"; | ||
| import { jsx as _jsx } from "react/jsx-runtime"; | ||
| import { jsxs as _jsxs } from "react/jsx-runtime"; | ||
| var _createNamespace = createNamespace('button-v2'), | ||
| _createNamespace2 = _slicedToArray(_createNamespace, 1), | ||
| bem = _createNamespace2[0]; | ||
| var ButtonV2 = function ButtonV2(_ref) { | ||
| var className = _ref.className, | ||
| _ref$type = _ref.type, | ||
| type = _ref$type === void 0 ? 'primary' : _ref$type, | ||
| _ref$state = _ref.state, | ||
| state = _ref$state === void 0 ? 'normal' : _ref$state, | ||
| _ref$theme = _ref.theme, | ||
| theme = _ref$theme === void 0 ? 'green' : _ref$theme, | ||
| _ref$disabled = _ref.disabled, | ||
| disabled = _ref$disabled === void 0 ? false : _ref$disabled, | ||
| onClick = _ref.onClick, | ||
| children = _ref.children, | ||
| _ref$needDebounce = _ref.needDebounce, | ||
| needDebounce = _ref$needDebounce === void 0 ? true : _ref$needDebounce, | ||
| _ref$debounceTime = _ref.debounceTime, | ||
| debounceTime = _ref$debounceTime === void 0 ? 500 : _ref$debounceTime, | ||
| _ref$immediate = _ref.immediate, | ||
| immediate = _ref$immediate === void 0 ? true : _ref$immediate, | ||
| _ref$hasIcon = _ref.hasIcon, | ||
| hasIcon = _ref$hasIcon === void 0 ? false : _ref$hasIcon; | ||
| // 确保 hasIcon 为真值时才显示图标,同时处理字符串 "true"/"false" 和布尔值的情况 | ||
| var shouldShowIcon = type === 'text' && (hasIcon === true || hasIcon === 'true'); | ||
| // 根据 theme 选择对应的图标(仅 text 类型支持 grey 和 green 主题) | ||
| var iconSrc = shouldShowIcon ? theme === 'grey' ? BlackIcon : theme === 'green' ? GreenIcon : null : null; | ||
| // 内部状态:跟踪按钮是否被按下 | ||
| var _useState = useState(false), | ||
| _useState2 = _slicedToArray(_useState, 2), | ||
| isPressed = _useState2[0], | ||
| setIsPressed = _useState2[1]; | ||
| // 内部状态:跟踪文本是否超过一行(用于 text 类型对齐) | ||
| var _useState3 = useState(false), | ||
| _useState4 = _slicedToArray(_useState3, 2), | ||
| isMultiLine = _useState4[0], | ||
| setIsMultiLine = _useState4[1]; | ||
| var textRef = useRef(null); | ||
| // 计算实际显示的状态 | ||
| // 如果 state 是 'disable',保持 'disable' | ||
| // 如果 state 是 'normal' 且按钮被按下,显示 'press' | ||
| // 否则使用传入的 state | ||
| var actualState = state === 'disable' ? 'disable' : isPressed && state === 'normal' ? 'press' : state; | ||
| // 检测文本是否超过一行(仅对 text 类型) | ||
| useEffect(function () { | ||
| if (type === 'text' && textRef.current) { | ||
| // 使用 setTimeout 确保 DOM 已经渲染完成 | ||
| var timer = setTimeout(function () { | ||
| var element = textRef.current; | ||
| if (!element) return; | ||
| // 获取元素的 line-height | ||
| var lineHeight = parseFloat(getComputedStyle(element).lineHeight) || 18; | ||
| // 创建一个临时元素来测量文本的真实高度(不受 line-clamp 限制) | ||
| var measureElement = document.createElement('span'); | ||
| measureElement.style.position = 'absolute'; | ||
| measureElement.style.visibility = 'hidden'; | ||
| measureElement.style.display = 'block'; | ||
| measureElement.style.width = "".concat(element.offsetWidth || 345, "px"); | ||
| measureElement.style.fontFamily = getComputedStyle(element).fontFamily; | ||
| measureElement.style.fontSize = getComputedStyle(element).fontSize; | ||
| measureElement.style.fontWeight = getComputedStyle(element).fontWeight; | ||
| measureElement.style.lineHeight = getComputedStyle(element).lineHeight; | ||
| measureElement.style.wordBreak = 'break-word'; | ||
| measureElement.textContent = element.textContent || ''; | ||
| document.body.appendChild(measureElement); | ||
| var realHeight = measureElement.offsetHeight; | ||
| document.body.removeChild(measureElement); | ||
| // 如果真实高度大于行高,说明超过一行 | ||
| setIsMultiLine(realHeight > lineHeight); | ||
| }, 0); | ||
| return function () { | ||
| return clearTimeout(timer); | ||
| }; | ||
| } | ||
| }, [children, type]); | ||
| var buttonClasses = clsx(className, bem('', _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "type-".concat(type), true), "state-".concat(actualState), true), "color-".concat(theme), true), "disabled", disabled || state === 'disable'), 'text-multi-line', type === 'text' && isMultiLine), 'text-single-line', type === 'text' && !isMultiLine))); | ||
| // 普通点击事件 | ||
| var handleClick = function handleClick(event) { | ||
| if (!disabled && state !== 'disable') { | ||
| onClick === null || onClick === void 0 || onClick(event); | ||
| } | ||
| }; | ||
| // 防抖点击事件 | ||
| var handleDebounceClick = useDebounce(function (event) { | ||
| handleClick(event); | ||
| }, debounceTime, immediate); | ||
| // 组件卸载时清理防抖定时器,避免内存泄漏 | ||
| useEffect(function () { | ||
| return function () { | ||
| var _handleDebounceClick$; | ||
| handleDebounceClick === null || handleDebounceClick === void 0 || (_handleDebounceClick$ = handleDebounceClick.cancel) === null || _handleDebounceClick$ === void 0 || _handleDebounceClick$.call(handleDebounceClick); | ||
| }; | ||
| }, [handleDebounceClick]); | ||
| // 鼠标按下事件 | ||
| var handleMouseDown = function handleMouseDown() { | ||
| if (!disabled && state !== 'disable' && state === 'normal') { | ||
| setIsPressed(true); | ||
| } | ||
| }; | ||
| // 鼠标释放事件 | ||
| var handleMouseUp = function handleMouseUp() { | ||
| setIsPressed(false); | ||
| }; | ||
| // 鼠标离开事件(防止鼠标移出按钮时状态不恢复) | ||
| var handleMouseLeave = function handleMouseLeave() { | ||
| setIsPressed(false); | ||
| }; | ||
| return /*#__PURE__*/_jsxs("button", { | ||
| className: buttonClasses, | ||
| onClick: needDebounce ? handleDebounceClick : handleClick, | ||
| onMouseDown: handleMouseDown, | ||
| onMouseUp: handleMouseUp, | ||
| onMouseLeave: handleMouseLeave, | ||
| disabled: disabled || state === 'disable', | ||
| type: "button", | ||
| children: [/*#__PURE__*/_jsx("span", { | ||
| ref: textRef, | ||
| className: clsx(bem('text')), | ||
| children: children | ||
| }), shouldShowIcon && iconSrc && /*#__PURE__*/_jsx("span", { | ||
| className: clsx(bem('icon')), | ||
| children: /*#__PURE__*/_jsx("img", { | ||
| src: iconSrc, | ||
| alt: "" | ||
| }) | ||
| }), type === 'activity' && /*#__PURE__*/_jsx("span", { | ||
| className: clsx(bem('light')), | ||
| children: /*#__PURE__*/_jsx("img", { | ||
| src: LightIcon, | ||
| alt: "" | ||
| }) | ||
| })] | ||
| }); | ||
| }; | ||
| export default ButtonV2; |
| import React from 'react'; | ||
| export type ButtonType = 'activity' | 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'prompt' | 'text'; | ||
| export type ButtonState = 'normal' | 'press' | 'disable'; | ||
| export type ButtonColorType = 'green' | 'blue' | 'orange' | 'fresh' | 'yellow' | 'red' | 'black' | 'grey'; | ||
| export interface ButtonV2Props { | ||
| className?: string; | ||
| type?: ButtonType; | ||
| state?: ButtonState; | ||
| theme?: ButtonColorType; | ||
| disabled?: boolean; | ||
| onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void; | ||
| children?: React.ReactNode; | ||
| needDebounce?: boolean; | ||
| debounceTime?: number; | ||
| immediate?: boolean; | ||
| hasIcon?: boolean | string; | ||
| } |
| export {}; |
| // style/index.less | ||
| @import '../../styles/var.less'; | ||
| .@{prefix}-button-v2 { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| box-sizing: border-box; | ||
| width: 100%; | ||
| max-width: 100%; | ||
| border: none; | ||
| cursor: pointer; | ||
| transition: all 0.2s ease; | ||
| border-radius: 8px; | ||
| position: relative; | ||
| user-select: none; | ||
| outline: none; | ||
| // 参考 Text 组件实现文本省略号 | ||
| // 按钮内的文本内容样式 | ||
| .@{prefix}-button-v2__text { | ||
| display: -webkit-box; | ||
| -webkit-box-orient: vertical; | ||
| -webkit-line-clamp: 1; // 单行显示 | ||
| line-clamp: 1; // 标准属性 | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| word-break: break-word; | ||
| width: 100%; | ||
| max-width: 100%; | ||
| min-width: 0; // 允许 flex 项目收缩 | ||
| flex: 1; // 占据可用空间 | ||
| } | ||
| // 宽度限制规则 | ||
| // tertiary、quaternary、prompt 类型 | ||
| &.@{prefix}-button-v2--type-tertiary, | ||
| &.@{prefix}-button-v2--type-quaternary, | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| min-width: 80px; | ||
| max-width: 140px; | ||
| } | ||
| // text 类型 | ||
| &.@{prefix}-button-v2--type-text { | ||
| max-width: 332px; | ||
| } | ||
| // Activity 类型 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| min-width: 315px; | ||
| max-width: 345px; | ||
| } | ||
| // 禁用状态 | ||
| &.@{prefix}-button-v2--disabled { | ||
| cursor: not-allowed; | ||
| opacity: 0.6; | ||
| pointer-events: none; | ||
| } | ||
| // Activity 类型样式 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| height: 56px; | ||
| border-radius: 32px; | ||
| padding: var(--base-sm-16); | ||
| min-width: 315px; | ||
| max-width: 345px; | ||
| font: var(--func-body-b3-b); | ||
| text-transform: uppercase; | ||
| letter-spacing: 0.5px; | ||
| position: relative; | ||
| overflow: hidden; | ||
| // Activity 类型光效样式 | ||
| .@{prefix}-button-v2__light { | ||
| position: absolute; | ||
| top: -6.94px; | ||
| left: -5.71px; | ||
| width: 113px; | ||
| height: 79px; | ||
| opacity: 1; | ||
| mix-blend-mode: screen; | ||
| pointer-events: none; // 不响应鼠标事件 | ||
| z-index: 1; // 确保在内容之上 | ||
| img { | ||
| width: 100%; | ||
| height: 100%; | ||
| display: block; | ||
| object-fit: contain; | ||
| } | ||
| } | ||
| } | ||
| // Primary 类型样式 | ||
| &.@{prefix}-button-v2--type-primary { | ||
| height: 56px; | ||
| width: 100%; | ||
| border-radius: var(--base-rl-32); | ||
| padding: var(--base-sm-16); | ||
| min-width: 136px; | ||
| max-width: 345px; | ||
| font: var(--func-body-b3-b); | ||
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); | ||
| } | ||
| // Secondary 类型样式 | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| width: 100%; | ||
| height: 56px; | ||
| min-width: 136px; | ||
| max-width: 345px; | ||
| border-radius: var(--base-rl-32); | ||
| border-width: 1px; | ||
| border-style: solid; | ||
| padding: var(--base-sm-16); | ||
| background-color: transparent; | ||
| font: var(--func-body-b3-b); | ||
| } | ||
| // Tertiary 类型样式 | ||
| &.@{prefix}-button-v2--type-tertiary { | ||
| height: 40px; | ||
| border-radius: var(--base-rm-20); | ||
| padding-top: var(--base-sm-10); | ||
| padding-right: var(--base-sm-12); | ||
| padding-bottom: var(--base-sm-10); | ||
| padding-left: var(--base-sm-12); | ||
| font: var(--func-body-b4-b); | ||
| } | ||
| // Quaternary 类型样式 | ||
| &.@{prefix}-button-v2--type-quaternary { | ||
| height: 34px; | ||
| border-radius: 17px; | ||
| padding-top: var(--base-ss-8); | ||
| padding-right: var(--func-component-button); | ||
| padding-bottom: var(--base-ss-8); | ||
| padding-left: var(--func-component-button); | ||
| font: var(--func-caption-c1-b); | ||
| } | ||
| // Prompt 类型样式 | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| height: 28px; | ||
| border-radius: 14px; | ||
| padding-right: var(--base-ss-8); | ||
| padding-left: var(--base-ss-8); | ||
| font: var(--func-caption-c1-s); | ||
| border-width: 1px; | ||
| border-style: solid; | ||
| background-color: transparent; | ||
| } | ||
| // Text 类型样式 - 文本按钮,无背景色 | ||
| &.@{prefix}-button-v2--type-text { | ||
| width: 345px; | ||
| min-height: 26px; // 一行时的最小高度 | ||
| max-height: 44px; // 两行时的最大高度 | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| padding: 4px 12px; // 上下 4px,左右 12px(一行时 4+18+4=26px,两行时 4+36+4=44px) | ||
| font-family: var(--base-font-family); | ||
| font-weight: var(--base-font-weight-bold); | ||
| font-size: var(--base-font-size-12); | ||
| line-height: var(--base-line-height-18); | ||
| letter-spacing: 0%; | ||
| text-decoration: none; | ||
| box-shadow: none !important; | ||
| gap: 4px; // 文本和图标之间的间距(紧贴文本) | ||
| // 一行文本时:文本和图标作为一个整体居中,紧贴在一起 | ||
| &.@{prefix}-button-v2--text-single-line { | ||
| justify-content: center; | ||
| .@{prefix}-button-v2__text { | ||
| display: inline-block; // 单行时:使用 inline-block,让文本根据内容宽度 | ||
| flex: 0 1 auto; // 允许收缩,不允许扩展,根据内容宽度自适应 | ||
| width: auto; // 宽度自动,让文本自然适应内容 | ||
| min-width: 0; // 允许收缩到内容宽度 | ||
| max-width: 100%; // 确保不超过容器宽度(当文本很长时) | ||
| white-space: nowrap; // 单行时不换行 | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; // 超出部分显示省略号 | ||
| vertical-align: middle; // 垂直对齐 | ||
| } | ||
| .@{prefix}-button-v2__icon { | ||
| display: inline-flex; // 图标作为行内元素,紧跟文本 | ||
| flex: none; // 图标不占据额外空间,固定宽度 | ||
| vertical-align: middle; // 垂直对齐,与文本对齐 | ||
| margin-left: 1px; // 图标紧跟在文本后面,最小间距 1px | ||
| } | ||
| // 单行时移除 gap,让文本和图标紧贴 | ||
| gap: 0; | ||
| } | ||
| // 两行文本时:左对齐 | ||
| &.@{prefix}-button-v2--text-multi-line { | ||
| justify-content: flex-start; | ||
| .@{prefix}-button-v2__text { | ||
| display: -webkit-box; // 多行时:使用 -webkit-box | ||
| -webkit-box-orient: vertical; | ||
| -webkit-line-clamp: 2; // 最多两行 | ||
| line-clamp: 2; // 标准属性 | ||
| flex: 1; // 占据可用空间 | ||
| min-width: 0; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| word-break: break-word; | ||
| align-self: flex-start; // 文本顶部对齐(支持多行) | ||
| } | ||
| } | ||
| // Text 类型图标样式 - 在文本右侧水平垂直居中 | ||
| .@{prefix}-button-v2__icon { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| flex-shrink: 0; // 图标不收缩 | ||
| align-self: center; // 图标垂直居中 | ||
| color: inherit; // 继承父元素颜色,以便 currentColor 生效 | ||
| svg { | ||
| width: 8px; | ||
| height: 8px; | ||
| display: block; | ||
| flex-shrink: 0; | ||
| } | ||
| } | ||
| } | ||
| // 颜色类型样式 | ||
| // Green 颜色 | ||
| &.@{prefix}-button-v2--color-green { | ||
| &.@{prefix}-button-v2--state-normal { | ||
| background-color: var(--func-green-normal); | ||
| color: white; | ||
| border-color: var(--func-green-normal); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-green-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-green-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #baffaf 0%, | ||
| #60de5f 24.96%, | ||
| #0cbe49 75.34%, | ||
| #3fca58 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(0, 176, 56, 1) inset, | ||
| -2px 1px 3px 1px rgba(228, 255, 201, 0.25) inset, | ||
| 0 0.5px 0.5px 0 rgba(2, 167, 54, 1) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-green-500); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-green-500) !important; | ||
| } | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-press { | ||
| background-color: var(--func-green-press); | ||
| color: white; | ||
| border-color: var(--func-green-press); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-green-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-green-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #3fca58 0%, | ||
| #32a246 24.96%, | ||
| #32a246 75.34%, | ||
| #32a246 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(0, 176, 56, 1) inset, | ||
| -2px 1px 3px 1px rgba(228, 255, 201, 0.25) inset, | ||
| 0 0.5px 0.5px 0 rgba(2, 167, 54, 1) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-green-500); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-green-500) !important; | ||
| } | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-disable { | ||
| background-color: var(--func-green-disabled); | ||
| color: var(--base-green-300); | ||
| border-color: var(--func-green-disabled); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-green-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-green-300); | ||
| background-color: transparent; | ||
| } | ||
| // Activity 类型 disable 状态:使用 normal 状态的背景 + 50% 透明度 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| position: relative; | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #baffaf 0%, | ||
| #60de5f 24.96%, | ||
| #0cbe49 75.34%, | ||
| #3fca58 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px #00b038 inset, | ||
| -2px 1px 3px 1px #e4ffc940 inset, | ||
| 0 0.5px 0.5px 0 #02a736 inset, | ||
| -2px 2px 4.1px 0 #ffffff40 inset !important; | ||
| color: var(--func-text-light-primary) !important; | ||
| // 使用伪元素创建 50% 透明度的白色遮罩层,使背景变淡 | ||
| &::before { | ||
| content: ''; | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background: rgba(255, 255, 255, 0.5); | ||
| pointer-events: none; | ||
| z-index: 1; | ||
| } | ||
| // 确保文字内容在遮罩层之上,但不影响 flex 布局 | ||
| .@{prefix}-button-v2__text { | ||
| position: relative; | ||
| z-index: 2; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-green-500); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-green-500) !important; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Blue 颜色 | ||
| &.@{prefix}-button-v2--color-blue { | ||
| &.@{prefix}-button-v2--state-normal { | ||
| background-color: var(--func-blue-normal); | ||
| color: white; | ||
| border-color: var(--func-blue-normal); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-blue-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-blue-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #d0d8fa 0%, | ||
| #7289f0 24.96%, | ||
| #143be6 75.34%, | ||
| #143be6 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px var(--base-blue-700) inset, | ||
| -2px 1px 3px 1px rgba(192, 202, 247, 0.15) inset, | ||
| 0 0.5px 0.5px 0 var(--func-blue-normal) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-press { | ||
| background-color: var(--func-blue-press); | ||
| color: white; | ||
| border-color: var(--func-blue-press); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-blue-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-blue-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #a1b1f5 0%, | ||
| #102fb8 24.96%, | ||
| #102fb8 75.34%, | ||
| #102fb8 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px var(--base-blue-700) inset, | ||
| -2px 1px 3px 1px rgba(192, 202, 247, 0.15) inset, | ||
| 0 0.5px 0.5px 0 var(--func-blue-normal) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-disable { | ||
| background-color: var(--func-blue-disabled); | ||
| color: var(--base-blue-300); | ||
| border-color: var(--func-blue-disabled); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-blue-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-blue-300); | ||
| background-color: transparent; | ||
| } | ||
| // Activity 类型 disable 状态:使用 normal 状态的背景 + 50% 透明度 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| position: relative; | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #d0d8fa 0%, | ||
| #7289f0 24.96%, | ||
| #143be6 75.34%, | ||
| #143be6 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px var(--base-blue-700) inset, | ||
| -2px 1px 3px 1px #c0caf726 inset, | ||
| 0 0.5px 0.5px 0 var(--func-blue-normal) inset, | ||
| -2px 2px 4.1px 0 #ffffff40 inset !important; | ||
| color: var(--func-text-light-primary) !important; | ||
| // 使用伪元素创建 50% 透明度的白色遮罩层,使背景变淡 | ||
| &::before { | ||
| content: ''; | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background: rgba(255, 255, 255, 0.5); | ||
| pointer-events: none; | ||
| z-index: 1; | ||
| } | ||
| // 确保文字内容在遮罩层之上,但不影响 flex 布局 | ||
| .@{prefix}-button-v2__text { | ||
| position: relative; | ||
| z-index: 2; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Orange 颜色 | ||
| &.@{prefix}-button-v2--color-orange { | ||
| &.@{prefix}-button-v2--state-normal { | ||
| background-color: var(--func-orange-normal); | ||
| color: white; | ||
| border-color: var(--func-orange-normal); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-orange-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-orange-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #ffe188 0%, | ||
| #ffb030 24.96%, | ||
| #ff882c 75.34%, | ||
| #ff7022 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(251, 88, 0, 1) inset, | ||
| -2px 1px 3px 1px rgba(255, 241, 201, 0.25) inset, | ||
| 0 0.5px 0.5px 0 rgba(246, 104, 0, 1) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-press { | ||
| background-color: var(--func-orange-press); | ||
| color: white; | ||
| border-color: var(--func-orange-press); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-orange-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-orange-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #ec7f2a 0%, | ||
| #ec7f2a 24.96%, | ||
| #ec7f2a 75.34%, | ||
| #ec7f2a 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(251, 88, 0, 1) inset, | ||
| -2px 1px 3px 1px rgba(255, 241, 201, 0.25) inset, | ||
| 0 0.5px 0.5px 0 rgba(246, 104, 0, 1) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-disable { | ||
| background-color: var(--func-orange-disabled); | ||
| color: var(--base-orange-300); | ||
| border-color: var(--func-orange-disabled); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-orange-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-orange-300); | ||
| background-color: transparent; | ||
| } | ||
| // Activity 类型 disable 状态:使用 normal 状态的背景 + 50% 透明度 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| position: relative; | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #ffe188 0%, | ||
| #ffb030 24.96%, | ||
| #ff882c 75.34%, | ||
| #ff7022 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px #fb5800 inset, | ||
| -2px 1px 3px 1px #fff1c940 inset, | ||
| 0 0.5px 0.5px 0 #f66800 inset, | ||
| -2px 2px 4.1px 0 #ffffff40 inset !important; | ||
| color: var(--func-text-light-primary) !important; | ||
| // 使用伪元素创建 50% 透明度的白色遮罩层,使背景变淡 | ||
| &::before { | ||
| content: ''; | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background: rgba(255, 255, 255, 0.5); | ||
| pointer-events: none; | ||
| z-index: 1; | ||
| } | ||
| // 确保文字内容在遮罩层之上,但不影响 flex 布局 | ||
| .@{prefix}-button-v2__text { | ||
| position: relative; | ||
| z-index: 2; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Fresh 颜色 | ||
| &.@{prefix}-button-v2--color-fresh { | ||
| &.@{prefix}-button-v2--state-normal { | ||
| background-color: var(--func-fresh-normal); | ||
| color: white; | ||
| border-color: var(--func-fresh-normal); | ||
| &.@{prefix}-button-v2--type-primary { | ||
| color: var(--func-text-dark-primary) !important; | ||
| } | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-fresh-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-fresh-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #f2fdda 0%, | ||
| #d9fa90 24.96%, | ||
| #9fdc19 75.34%, | ||
| #bff646 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px var(--func-fresh-normal) inset, | ||
| -2px 1px 3px 1px rgba(217, 250, 144, 0.25) inset, | ||
| 0 0.5px 0.5px 0 var(--func-fresh-press) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: var(--func-text-dark-primary) !important; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-press { | ||
| background-color: var(--func-fresh-press); | ||
| color: white; | ||
| border-color: var(--func-fresh-press); | ||
| &.@{prefix}-button-v2--type-primary { | ||
| color: var(--func-text-dark-primary) !important; | ||
| } | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-fresh-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-fresh-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #9ac738 0%, | ||
| #9ac738 24.96%, | ||
| #9ac738 75.34%, | ||
| #9ac738 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px var(--func-fresh-normal) inset, | ||
| -2px 1px 3px 1px rgba(217, 250, 144, 0.25) inset, | ||
| 0 0.5px 0.5px 0 var(--func-fresh-press) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: var(--func-text-dark-primary) !important; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-disable { | ||
| background-color: var(--func-fresh-disabled); | ||
| color: var(--base-fresh-300); | ||
| border-color: var(--func-fresh-disabled); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-fresh-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-fresh-300); | ||
| background-color: transparent; | ||
| } | ||
| // Activity 类型 disable 状态:使用 normal 状态的背景 + 50% 透明度 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| position: relative; | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #f2fdda 0%, | ||
| #d9fa90 24.96%, | ||
| #9fdc19 75.34%, | ||
| #bff646 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px var(--func-fresh-normal) inset, | ||
| -2px 1px 3px 1px #d9fa9040 inset, | ||
| 0 0.5px 0.5px 0 var(--func-fresh-press) inset, | ||
| -2px 2px 4.1px 0 #ffffff40 inset !important; | ||
| color: var(--func-text-dark-primary) !important; | ||
| // 使用伪元素创建 50% 透明度的白色遮罩层,使背景变淡 | ||
| &::before { | ||
| content: ''; | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background: rgba(255, 255, 255, 0.5); | ||
| pointer-events: none; | ||
| z-index: 1; | ||
| } | ||
| // 确保文字内容在遮罩层之上,但不影响 flex 布局 | ||
| .@{prefix}-button-v2__text { | ||
| position: relative; | ||
| z-index: 2; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Yellow 颜色 | ||
| &.@{prefix}-button-v2--color-yellow { | ||
| &.@{prefix}-button-v2--state-normal { | ||
| background-color: var(--func-yellow-normal); | ||
| color: white; | ||
| border-color: var(--func-yellow-normal); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-yellow-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-yellow-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #ffefd6 0%, | ||
| #ffc059 24.96%, | ||
| #ffb030 75.34%, | ||
| #ffb030 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(239, 127, 8, 1) inset, | ||
| -2px 1px 3px 1px rgba(255, 191, 88, 0.15) inset, | ||
| 0 0.5px 0.5px 0 var(--base-yellow-500) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-press { | ||
| background-color: var(--func-yellow-press); | ||
| color: white; | ||
| border-color: var(--func-yellow-press); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-yellow-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-yellow-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #df9620 0%, | ||
| #df9620 24.96%, | ||
| #df9620 75.34%, | ||
| #df9620 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(239, 127, 8, 1) inset, | ||
| -2px 1px 3px 1px rgba(255, 191, 88, 0.15) inset, | ||
| 0 0.5px 0.5px 0 var(--base-yellow-500) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-disable { | ||
| background-color: var(--func-yellow-disabled); | ||
| color: var(--base-yellow-300); | ||
| border-color: var(--func-yellow-disabled); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-yellow-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-yellow-300); | ||
| background-color: transparent; | ||
| } | ||
| // Activity 类型 disable 状态:使用 normal 状态的背景 + 50% 透明度 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| position: relative; | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #ffefd6 0%, | ||
| #ffc059 24.96%, | ||
| #ffb030 75.34%, | ||
| #ffb030 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px #ef7f08 inset, | ||
| -2px 1px 3px 1px #ffbf5826 inset, | ||
| 0 0.5px 0.5px 0 var(--base-yellow-500) inset, | ||
| -2px 2px 4.1px 0 #ffffff40 inset !important; | ||
| color: var(--func-text-light-primary) !important; | ||
| // 使用伪元素创建 50% 透明度的白色遮罩层,使背景变淡 | ||
| &::before { | ||
| content: ''; | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background: rgba(255, 255, 255, 0.5); | ||
| pointer-events: none; | ||
| z-index: 1; | ||
| } | ||
| // 确保文字内容在遮罩层之上,但不影响 flex 布局 | ||
| .@{prefix}-button-v2__text { | ||
| position: relative; | ||
| z-index: 2; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Red 颜色 | ||
| &.@{prefix}-button-v2--color-red { | ||
| &.@{prefix}-button-v2--state-normal { | ||
| background-color: var(--func-warning-normal); | ||
| color: white; | ||
| border-color: var(--func-warning-normal); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-warning-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-warning-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #fff0ef 0%, | ||
| #ffb9b5 24.96%, | ||
| #ff5d54 75.34%, | ||
| #ff3b30 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(255, 59, 48, 1) inset, | ||
| -2px 1px 3px 1px rgba(255, 59, 48, 0.25) inset, | ||
| 0 0.5px 0.5px 0 rgba(255, 59, 48, 1) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-press { | ||
| background-color: var(--func-warning-press); | ||
| color: white; | ||
| border-color: var(--func-warning-press); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-warning-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-warning-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #fff0ef 0%, | ||
| #ffb9b5 24.96%, | ||
| #ff5d54 75.34%, | ||
| #ff3b30 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(255, 59, 48, 1) inset, | ||
| -2px 1px 3px 1px rgba(255, 59, 48, 0.25) inset, | ||
| 0 0.5px 0.5px 0 rgba(255, 59, 48, 1) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-disable { | ||
| background-color: var(--func-warning-disable); | ||
| color: var(--base-red-300); | ||
| border-color: var(--func-warning-disable); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-red-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-red-300); | ||
| background-color: transparent; | ||
| } | ||
| // Activity 类型 disable 状态:使用 normal 状态的背景 + 50% 透明度 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| position: relative; | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #fff0ef 0%, | ||
| #ffb9b5 24.96%, | ||
| #ff5d54 75.34%, | ||
| #ff3b30 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px #ff3b30 inset, | ||
| -2px 1px 3px 1px #ff3b3040 inset, | ||
| 0 0.5px 0.5px 0 #ff3b30 inset, | ||
| -2px 2px 4.1px 0 #ffffff40 inset !important; | ||
| color: var(--func-text-light-primary) !important; | ||
| // 使用伪元素创建 50% 透明度的白色遮罩层,使背景变淡 | ||
| &::before { | ||
| content: ''; | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background: rgba(255, 255, 255, 0.5); | ||
| pointer-events: none; | ||
| z-index: 1; | ||
| } | ||
| // 确保文字内容在遮罩层之上,但不影响 flex 布局 | ||
| .@{prefix}-button-v2__text { | ||
| position: relative; | ||
| z-index: 2; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Black 颜色 | ||
| &.@{prefix}-button-v2--color-black { | ||
| &.@{prefix}-button-v2--state-normal { | ||
| background-color: var(--func-grey-normal); | ||
| color: white; | ||
| border-color: var(--func-grey-normal); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-grey-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-grey-normal); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #535353 0%, | ||
| #525252 24.96%, | ||
| #000 75.34%, | ||
| #000 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(0, 0, 0, 1) inset, | ||
| -2px 1px 3px 1px rgba(0, 0, 0, 0.25) inset, | ||
| 0 0.5px 0.5px 0 rgba(0, 0, 0, 1) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-grey-200); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-grey-200) !important; | ||
| } | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-press { | ||
| background-color: var(--func-grey-press); | ||
| color: white; | ||
| border-color: var(--func-grey-press); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--func-grey-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--func-grey-press); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-activity { | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #dedede 0%, | ||
| #666 24.96%, | ||
| #666 75.34%, | ||
| #666 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px rgba(0, 0, 0, 1) inset, | ||
| -2px 1px 3px 1px rgba(0, 0, 0, 0.25) inset, | ||
| 0 0.5px 0.5px 0 rgba(0, 0, 0, 1) inset, | ||
| -2px 2px 4.1px 0 rgba(255, 255, 255, 0.25) inset !important; | ||
| color: white; | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-grey-200); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-grey-200) !important; | ||
| } | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-disable { | ||
| background-color: var(--func-grey-disable); | ||
| color: var(--base-grey-300); | ||
| border-color: var(--func-grey-disable); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-grey-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-grey-300); | ||
| background-color: transparent; | ||
| } | ||
| // Activity 类型 disable 状态:使用 normal 状态的背景 + 50% 透明度 | ||
| &.@{prefix}-button-v2--type-activity { | ||
| position: relative; | ||
| background: linear-gradient( | ||
| 180deg, | ||
| #535353 0%, | ||
| #525252 24.96%, | ||
| #000 75.34%, | ||
| #000 162.96% | ||
| ) !important; | ||
| box-shadow: | ||
| 0 2px 7.5px 1px #000 inset, | ||
| -2px 1px 3px 1px #00000040 inset, | ||
| 0 0.5px 0.5px 0 #000 inset, | ||
| -2px 2px 4.1px 0 #ffffff40 inset !important; | ||
| color: var(--func-text-light-primary) !important; | ||
| // 使用伪元素创建 50% 透明度的白色遮罩层,使背景变淡 | ||
| &::before { | ||
| content: ''; | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background: rgba(255, 255, 255, 0.5); | ||
| pointer-events: none; | ||
| z-index: 1; | ||
| } | ||
| // 确保文字内容在遮罩层之上,但不影响 flex 布局 | ||
| .@{prefix}-button-v2__text { | ||
| position: relative; | ||
| z-index: 2; | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-grey-200); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-grey-200) !important; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // Grey 颜色 | ||
| &.@{prefix}-button-v2--color-grey { | ||
| &.@{prefix}-button-v2--state-normal { | ||
| background-color: var(--base-grey-200); | ||
| color: var(--func-grey-normal); | ||
| border-color: var(--base-grey-200); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-grey-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-grey-300); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-grey-200); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-grey-200) !important; | ||
| } | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-press { | ||
| background-color: var(--base-grey-300); | ||
| color: var(--func-grey-normal); | ||
| border-color: var(--base-grey-300); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-grey-400); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-grey-400); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-grey-200); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-grey-200) !important; | ||
| } | ||
| } | ||
| } | ||
| &.@{prefix}-button-v2--state-disable { | ||
| background-color: var(--func-grey-disable); | ||
| color: var(--base-grey-200); | ||
| border-color: var(--func-grey-disable); | ||
| &.@{prefix}-button-v2--type-secondary { | ||
| color: var(--base-grey-200); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-prompt { | ||
| color: var(--base-grey-200); | ||
| background-color: transparent; | ||
| } | ||
| &.@{prefix}-button-v2--type-text { | ||
| color: var(--base-grey-200); | ||
| background-color: transparent !important; | ||
| border: none !important; | ||
| .@{prefix}-button-v2__icon { | ||
| color: var(--base-grey-200) !important; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // 特殊文字颜色规则 | ||
| // 当 type 是 activity 且 colorType 是 fresh 时 | ||
| &.@{prefix}-button-v2--color-fresh { | ||
| &.@{prefix}-button-v2--type-activity { | ||
| // normal 和 press 状态使用 Func/Text/Dark/Primary | ||
| &.@{prefix}-button-v2--state-normal, | ||
| &.@{prefix}-button-v2--state-press { | ||
| color: var(--func-text-dark-primary) !important; | ||
| } | ||
| // disable 状态使用 Func/Text/Light/Primary | ||
| &.@{prefix}-button-v2--state-disable { | ||
| color: var(--func-text-light-primary) !important; | ||
| } | ||
| } | ||
| // 当 type 是 quaternary 且 colorType 是 fresh 时 | ||
| &.@{prefix}-button-v2--type-quaternary { | ||
| // normal 和 press 状态使用 Func/Text/Dark/Primary | ||
| &.@{prefix}-button-v2--state-normal, | ||
| &.@{prefix}-button-v2--state-press { | ||
| color: var(--func-text-dark-primary) !important; | ||
| } | ||
| } | ||
| // 当 type 是 tertiary 且 colorType 是 fresh 时 | ||
| &.@{prefix}-button-v2--type-tertiary { | ||
| // normal 和 press 状态使用 Func/Text/Dark/Primary | ||
| &.@{prefix}-button-v2--state-normal, | ||
| &.@{prefix}-button-v2--state-press { | ||
| color: var(--func-text-dark-primary) !important; | ||
| } | ||
| } | ||
| } | ||
| // Primary 类型文本颜色规则 | ||
| // 当 type 是 primary 时,所有主题和状态都使用 Func/Text/Light/Primary | ||
| &.@{prefix}-button-v2--type-primary { | ||
| &.@{prefix}-button-v2--state-normal, | ||
| &.@{prefix}-button-v2--state-press, | ||
| &.@{prefix}-button-v2--state-disable { | ||
| color: var(--func-text-light-primary) !important; | ||
| } | ||
| } | ||
| // Tertiary 类型文本颜色规则 | ||
| // 当 type 是 tertiary 时,所有主题和状态都使用 Func/Text/Light/Primary(与 primary 保持一致) | ||
| &.@{prefix}-button-v2--type-tertiary { | ||
| &.@{prefix}-button-v2--state-normal, | ||
| &.@{prefix}-button-v2--state-press, | ||
| &.@{prefix}-button-v2--state-disable { | ||
| color: var(--func-text-light-primary) !important; | ||
| } | ||
| } | ||
| // Quaternary 类型文本颜色规则 | ||
| // 当 type 是 quaternary 时,所有主题和状态都使用 Func/Text/Light/Primary(与 primary 保持一致) | ||
| &.@{prefix}-button-v2--type-quaternary { | ||
| &.@{prefix}-button-v2--state-normal, | ||
| &.@{prefix}-button-v2--state-press, | ||
| &.@{prefix}-button-v2--state-disable { | ||
| color: var(--func-text-light-primary) !important; | ||
| } | ||
| } | ||
| // 焦点状态 | ||
| &:focus-visible { | ||
| outline: 2px solid currentcolor; | ||
| outline-offset: 2px; | ||
| } | ||
| } |
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M12.4599 4.53901L8.99898 7.99999L12.4599 11.4613C12.7358 11.7372 12.7358 12.1841 12.4599 12.4599C12.1841 12.7358 11.7372 12.7358 11.4613 12.4599L7.99999 8.99898L4.53901 12.4599C4.26317 12.7358 3.81622 12.7358 3.54038 12.4599C3.26454 12.1841 3.26454 11.7372 3.54038 11.4613L7.00135 7.99999L3.54038 4.53901C3.26454 4.26317 3.26454 3.81622 3.54038 3.54038C3.81622 3.26454 4.26317 3.26454 4.53901 3.54038L7.99999 7.00135L11.4613 3.54038C11.7372 3.26454 12.1841 3.26454 12.4599 3.54038C12.7358 3.81622 12.7358 4.26317 12.4599 4.53901Z" fill="#666666"/> | ||
| </svg> |
Sorry, the diff of this file is not supported yet
| <svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <g clip-path="url(#clip0_253_7876)"> | ||
| <path d="M5.64302 3.8234L2.71099 0.891369C2.67603 0.856492 2.63152 0.832751 2.58308 0.82314C2.53464 0.813529 2.48444 0.818479 2.43881 0.837366C2.39318 0.856252 2.35417 0.888229 2.32669 0.929263C2.29922 0.970297 2.28451 1.01855 2.28442 1.06793V6.93199C2.28435 6.98144 2.29895 7.0298 2.32637 7.07096C2.35378 7.11211 2.39279 7.14421 2.43845 7.16319C2.48411 7.18218 2.53438 7.18719 2.58289 7.17761C2.6314 7.16802 2.67598 7.14426 2.71099 7.10934L5.64302 4.17653C5.66626 4.15337 5.6847 4.12585 5.69729 4.09556C5.70987 4.06526 5.71635 4.03277 5.71635 3.99996C5.71635 3.96715 5.70987 3.93467 5.69729 3.90437C5.6847 3.87407 5.66626 3.84655 5.64302 3.8234Z" fill="black"/> | ||
| </g> | ||
| <defs> | ||
| <clipPath id="clip0_253_7876"> | ||
| <rect width="8" height="8" fill="white"/> | ||
| </clipPath> | ||
| </defs> | ||
| </svg> |
| import React from 'react'; | ||
| import { ListCellProps } from './PropsType'; | ||
| import './style/index.less'; | ||
| declare const ListCell: React.FC<ListCellProps>; | ||
| export default ListCell; |
| import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
| /** | ||
| * 统一的列表单元格组件 | ||
| * 功能:支持纯文案、文案+图标、文案+注释、文案+注释+图标四种模式 | ||
| * 特点:通过 props 控制显示内容,支持多行显示和截断 | ||
| */ | ||
| import clsx from 'clsx'; | ||
| import React from 'react'; | ||
| import { createNamespace } from "../utils"; | ||
| import BlackIcon from "./icon/black.png"; | ||
| import "./style/index.less"; | ||
| import { jsx as _jsx } from "react/jsx-runtime"; | ||
| import { jsxs as _jsxs } from "react/jsx-runtime"; | ||
| var _createNamespace = createNamespace('listcell'), | ||
| _createNamespace2 = _slicedToArray(_createNamespace, 1), | ||
| bem = _createNamespace2[0]; | ||
| var ListCell = function ListCell(_ref) { | ||
| var className = _ref.className, | ||
| style = _ref.style, | ||
| leftText = _ref.leftText, | ||
| rightText = _ref.rightText, | ||
| rightNote = _ref.rightNote, | ||
| rightIcon = _ref.rightIcon, | ||
| _ref$disabled = _ref.disabled, | ||
| disabled = _ref$disabled === void 0 ? false : _ref$disabled, | ||
| onClick = _ref.onClick; | ||
| var handleClick = function handleClick(event) { | ||
| if (!disabled && onClick) { | ||
| onClick(event); | ||
| } | ||
| }; | ||
| // 判断是否有图标 | ||
| var hasIcon = !!rightIcon; | ||
| // 判断是否有注释 | ||
| var hasNote = !!rightNote; | ||
| return /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(className, bem('', { | ||
| disabled: disabled, | ||
| 'with-icon': !!rightIcon, | ||
| 'with-note': !!rightNote | ||
| })), | ||
| style: style, | ||
| onClick: handleClick, | ||
| role: "button", | ||
| tabIndex: disabled ? -1 : 0, | ||
| "aria-disabled": disabled, | ||
| children: [/*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('left-text')), | ||
| children: /*#__PURE__*/_jsx("span", { | ||
| children: leftText | ||
| }) | ||
| }), hasNote ? | ||
| /*#__PURE__*/ | ||
| // 有注释的情况:显示主文案和注释 | ||
| _jsxs("div", { | ||
| className: clsx(bem('right-content')), | ||
| children: [/*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('right-text')), | ||
| children: /*#__PURE__*/_jsx("span", { | ||
| children: rightText | ||
| }) | ||
| }), /*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('right-note')), | ||
| children: /*#__PURE__*/_jsx("span", { | ||
| children: rightNote | ||
| }) | ||
| })] | ||
| }) : | ||
| /*#__PURE__*/ | ||
| // 无注释的情况:只显示主文案 | ||
| _jsx("div", { | ||
| className: clsx(bem('right-text')), | ||
| children: /*#__PURE__*/_jsx("span", { | ||
| children: rightText | ||
| }) | ||
| }), hasIcon && /*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('right-icon')), | ||
| children: rightIcon === true ? /*#__PURE__*/_jsx("img", { | ||
| src: BlackIcon, | ||
| alt: "" | ||
| }) : rightIcon | ||
| })] | ||
| }); | ||
| }; | ||
| export default ListCell; |
| import React from 'react'; | ||
| export interface ListCellProps { | ||
| className?: string; | ||
| style?: React.CSSProperties; | ||
| leftText: string; | ||
| rightText: string; | ||
| rightNote?: string; | ||
| rightIcon?: React.ReactNode | boolean; | ||
| disabled?: boolean; | ||
| onClick?: (e: React.MouseEvent<HTMLDivElement>) => void; | ||
| } |
| export {}; |
| @import '../../styles/var.less'; | ||
| :root { | ||
| --easy-listcell-text-color: @dark-black; | ||
| --easy-listcell-note-color: @dark-gray; | ||
| --easy-listcell-active-bg: #f1f1f1; | ||
| --easy-listcell-icon-size: 8px; | ||
| --easy-listcell-icon-gap: 8px; | ||
| --easy-listcell-content-gap: 12px; | ||
| } | ||
| .@{prefix}-listcell { | ||
| width: 315px; | ||
| min-height: 48px; | ||
| max-height: 56px; | ||
| padding: @padding-xs 0; | ||
| box-sizing: border-box; | ||
| position: relative; | ||
| background-color: transparent; | ||
| display: flex; | ||
| align-items: center; | ||
| gap: var(--easy-listcell-content-gap); | ||
| // 交互状态 | ||
| &:active { | ||
| background-color: var(--easy-listcell-active-bg); | ||
| } | ||
| // 左侧文案 | ||
| &__left-text { | ||
| width: 50%; | ||
| min-width: 0; | ||
| height: 20px; | ||
| min-height: 20px; | ||
| max-height: 40px; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: flex-start; | ||
| font-family: Poppins, sans-serif; | ||
| font-size: @font-size-md; | ||
| line-height: @line-height-md; | ||
| font-weight: 400; | ||
| color: var(--easy-listcell-text-color); | ||
| > span { | ||
| text-align: left; | ||
| display: -webkit-box; | ||
| -webkit-box-orient: vertical; | ||
| -webkit-line-clamp: 2; | ||
| line-clamp: 2; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| word-break: break-word; | ||
| } | ||
| } | ||
| // 右侧文案(无注释时) | ||
| &__right-text { | ||
| width: 50%; | ||
| min-width: 0; | ||
| height: 20px; | ||
| min-height: 20px; | ||
| max-height: 40px; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: flex-end; | ||
| font-family: Poppins, sans-serif; | ||
| font-size: @font-size-md; | ||
| line-height: @line-height-md; | ||
| font-weight: 700; | ||
| color: var(--easy-listcell-text-color); | ||
| > span { | ||
| text-align: right; | ||
| display: -webkit-box; | ||
| -webkit-box-orient: vertical; | ||
| -webkit-line-clamp: 2; | ||
| line-clamp: 2; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| word-break: break-word; | ||
| } | ||
| } | ||
| // 右侧内容容器(有注释时) | ||
| &__right-content { | ||
| width: 50%; | ||
| min-width: 0; | ||
| height: 42px; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 4px; | ||
| justify-content: flex-start; | ||
| // 右侧主文案(在内容容器内) | ||
| .@{prefix}-listcell__right-text { | ||
| width: 100%; | ||
| height: 20px; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: flex-end; | ||
| font-family: Poppins, sans-serif; | ||
| font-size: @font-size-md; | ||
| line-height: @line-height-md; | ||
| font-weight: 700; | ||
| color: var(--easy-listcell-text-color); | ||
| > span { | ||
| text-align: right; | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| width: 100%; | ||
| display: block; | ||
| } | ||
| } | ||
| } | ||
| // 右侧注释 | ||
| &__right-note { | ||
| width: 100%; | ||
| height: 18px; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: flex-end; | ||
| font-family: Poppins, sans-serif; | ||
| font-size: @font-size-sm; | ||
| line-height: @line-height-sm; | ||
| font-weight: 400; | ||
| color: var(--easy-listcell-note-color); | ||
| > span { | ||
| text-align: right; | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| width: 100%; | ||
| display: block; | ||
| } | ||
| } | ||
| // 右侧图标 | ||
| &__right-icon { | ||
| position: absolute; | ||
| top: 50%; | ||
| transform: translateY(-50%); | ||
| right: 0; | ||
| width: var(--easy-listcell-icon-size); | ||
| height: var(--easy-listcell-icon-size); | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| z-index: 1; | ||
| img { | ||
| width: 100%; | ||
| height: 100%; | ||
| object-fit: contain; | ||
| display: block; | ||
| } | ||
| } | ||
| // 有图标时的布局调整 | ||
| &--with-icon { | ||
| .@{prefix}-listcell__right-text { | ||
| margin-right: calc( | ||
| var(--easy-listcell-icon-size) + var(--easy-listcell-icon-gap) | ||
| ); | ||
| } | ||
| .@{prefix}-listcell__right-content { | ||
| margin-right: calc( | ||
| var(--easy-listcell-icon-size) + var(--easy-listcell-icon-gap) | ||
| ); | ||
| } | ||
| } | ||
| // 有注释时的布局调整 | ||
| &--with-note { | ||
| // 注释模式下,右侧文案不显示省略号 | ||
| .@{prefix}-listcell__right-text > span { | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| // 不设置 text-overflow: ellipsis,按需求去掉省略号 | ||
| } | ||
| } | ||
| // 有注释且有图标时的布局调整 | ||
| &--with-note.@{prefix}-listcell--with-icon { | ||
| .@{prefix}-listcell__right-content { | ||
| margin-right: calc( | ||
| var(--easy-listcell-icon-size) + var(--easy-listcell-icon-gap) | ||
| ); | ||
| } | ||
| .@{prefix}-listcell__right-text > span { | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| } | ||
| .@{prefix}-listcell__right-note > span { | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| } | ||
| } | ||
| } |
Sorry, the diff of this file is not supported yet
| import React from 'react'; | ||
| import { PopupInstanceType, PopupProps } from './PropsType'; | ||
| import './style/index.less'; | ||
| declare const Popup: React.ForwardRefExoticComponent<PopupProps & React.RefAttributes<PopupInstanceType>>; | ||
| export default Popup; |
| import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
| import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
| import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
| import clsx from 'clsx'; | ||
| import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'; | ||
| import Button from "../button-v2"; | ||
| import Overlay from "../overlay"; | ||
| import { createNamespace } from "../utils"; | ||
| import Close from "./icon/close.png"; | ||
| import "./style/index.less"; | ||
| import { jsx as _jsx } from "react/jsx-runtime"; | ||
| import { jsxs as _jsxs } from "react/jsx-runtime"; | ||
| import { Fragment as _Fragment } from "react/jsx-runtime"; | ||
| var _createNamespace = createNamespace('popupV2'), | ||
| _createNamespace2 = _slicedToArray(_createNamespace, 1), | ||
| bem = _createNamespace2[0]; | ||
| var Popup = /*#__PURE__*/forwardRef(function (props, ref) { | ||
| var visible = props.visible, | ||
| title = props.title, | ||
| onClose = props.onClose, | ||
| children = props.children, | ||
| className = props.className, | ||
| _props$closeable = props.closeable, | ||
| closeable = _props$closeable === void 0 ? true : _props$closeable, | ||
| buttonPrimary = props.buttonPrimary, | ||
| onConfirmClick = props.onConfirmClick, | ||
| buttonSecondary = props.buttonSecondary, | ||
| buttonTip = props.buttonTip, | ||
| _props$overlay = props.overlay, | ||
| overlay = _props$overlay === void 0 ? true : _props$overlay, | ||
| _props$position = props.position, | ||
| position = _props$position === void 0 ? 'center' : _props$position, | ||
| style = props.style, | ||
| overlayStyle = props.overlayStyle, | ||
| overlayClass = props.overlayClass, | ||
| _props$closeOnClickOv = props.closeOnClickOverlay, | ||
| closeOnClickOverlay = _props$closeOnClickOv === void 0 ? true : _props$closeOnClickOv, | ||
| _props$safeAreaInsetB = props.safeAreaInsetBottom, | ||
| safeAreaInsetBottom = _props$safeAreaInsetB === void 0 ? false : _props$safeAreaInsetB; | ||
| var _useState = useState(visible), | ||
| _useState2 = _slicedToArray(_useState, 2), | ||
| active = _useState2[0], | ||
| setActive = _useState2[1]; | ||
| var popupRef = useRef(null); | ||
| useEffect(function () { | ||
| if (visible) { | ||
| setActive(true); | ||
| } else { | ||
| var timer = setTimeout(function () { | ||
| setActive(false); | ||
| }, 300); | ||
| return function () { | ||
| clearTimeout(timer); | ||
| }; | ||
| } | ||
| }, [visible]); | ||
| var onClickOverlay = function onClickOverlay(e) { | ||
| var _props$onClickOverlay; | ||
| (_props$onClickOverlay = props.onClickOverlay) === null || _props$onClickOverlay === void 0 || _props$onClickOverlay.call(props, e); | ||
| if (closeOnClickOverlay) { | ||
| onClose === null || onClose === void 0 || onClose(); | ||
| } | ||
| }; | ||
| var renderOverlay = function renderOverlay() { | ||
| if (overlay) { | ||
| return /*#__PURE__*/_jsx(Overlay, { | ||
| visible: visible, | ||
| className: overlayClass, | ||
| style: overlayStyle, | ||
| onClick: onClickOverlay, | ||
| frostedGlass: props.frostedGlass, | ||
| lockScroll: props.lockScroll | ||
| }); | ||
| } | ||
| return null; | ||
| }; | ||
| useImperativeHandle(ref, function () { | ||
| return { | ||
| popupRef: popupRef, | ||
| close: function close() { | ||
| onClose === null || onClose === void 0 || onClose(); | ||
| } | ||
| }; | ||
| }); | ||
| var renderCloseIcon = function renderCloseIcon() { | ||
| if (closeable) { | ||
| return /*#__PURE__*/_jsx("img", { | ||
| className: clsx(bem('close')), | ||
| onClick: function onClick(e) { | ||
| var _props$onClickCloseIc; | ||
| e.stopPropagation(); | ||
| props === null || props === void 0 || (_props$onClickCloseIc = props.onClickCloseIcon) === null || _props$onClickCloseIc === void 0 || _props$onClickCloseIc.call(props, e); | ||
| onClose === null || onClose === void 0 || onClose(); | ||
| }, | ||
| src: Close, | ||
| alt: "" | ||
| }); | ||
| } | ||
| return null; | ||
| }; | ||
| var renderTitle = function renderTitle() { | ||
| if (title) { | ||
| return /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(bem('header')), | ||
| children: [/*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('title')), | ||
| children: title | ||
| }), renderCloseIcon()] | ||
| }); | ||
| } | ||
| return null; | ||
| }; | ||
| var renderButton = function renderButton() { | ||
| // 如果没有任何按钮相关属性,不渲染 | ||
| if (!buttonPrimary && !buttonSecondary && !buttonTip) { | ||
| return null; | ||
| } | ||
| var hasSecondaryButton = buttonPrimary && buttonSecondary; | ||
| var hasTip = buttonTip; | ||
| return /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(bem('footer')), | ||
| children: [hasSecondaryButton ? /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(bem('buttons')), | ||
| children: [/*#__PURE__*/_jsx(Button, { | ||
| type: "secondary", | ||
| theme: "green", | ||
| state: "normal", | ||
| onClick: props.onSecondaryClick, | ||
| className: clsx(bem('buttons', ['button', 'secondary'])), | ||
| children: buttonSecondary | ||
| }), /*#__PURE__*/_jsx(Button, { | ||
| type: "primary", | ||
| theme: "green", | ||
| state: "normal", | ||
| onClick: onConfirmClick, | ||
| className: clsx(bem('buttons', ['button', 'primary'])), | ||
| children: buttonPrimary | ||
| })] | ||
| }) : buttonPrimary && /*#__PURE__*/_jsx(Button, { | ||
| type: "primary", | ||
| theme: "green", | ||
| state: "normal", | ||
| onClick: onConfirmClick, | ||
| className: clsx(bem('button', ['primary'])), | ||
| children: buttonPrimary | ||
| }), hasTip && /*#__PURE__*/_jsx(Button, { | ||
| type: "text", | ||
| theme: "grey", | ||
| className: clsx(bem('tip')), | ||
| onClick: props.onTipClick, | ||
| children: buttonTip | ||
| })] | ||
| }); | ||
| }; | ||
| var renderChildren = function renderChildren() { | ||
| if (children) { | ||
| return /*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('content')), | ||
| children: children | ||
| }); | ||
| } | ||
| return null; | ||
| }; | ||
| return /*#__PURE__*/_jsxs(_Fragment, { | ||
| children: [renderOverlay(), /*#__PURE__*/_jsx("div", { | ||
| ref: popupRef, | ||
| className: clsx(bem('container', { | ||
| hidden: !active | ||
| })), | ||
| children: /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(bem('wrapper', _defineProperty(_defineProperty({ | ||
| visible: visible | ||
| }, position, position), 'safe-area-inset-bottom', safeAreaInsetBottom)), [className]), | ||
| style: _objectSpread({}, style), | ||
| children: [renderTitle(), renderChildren(), renderButton()] | ||
| }) | ||
| })] | ||
| }); | ||
| }); | ||
| export default Popup; |
| /// <reference types="react" /> | ||
| export interface PopupProps { | ||
| visible: boolean; | ||
| className?: string; | ||
| overlayClass?: string; | ||
| overlayStyle?: React.CSSProperties; | ||
| style?: React.CSSProperties; | ||
| title?: string; | ||
| position?: 'bottom' | 'center'; | ||
| children?: React.ReactNode; | ||
| buttonPrimary?: string; | ||
| buttonSecondary?: string; | ||
| buttonTip?: string; | ||
| closeOnClickOverlay?: boolean; | ||
| closeable?: boolean; | ||
| onClickCloseIcon?: (e: React.MouseEvent) => void; | ||
| overlay?: boolean; | ||
| onClose?: () => void; | ||
| onConfirmClick?: () => void; | ||
| onSecondaryClick?: () => void; | ||
| onTipClick?: () => void; | ||
| onClickOverlay?: (e: React.MouseEvent) => void; | ||
| frostedGlass?: boolean; | ||
| lockScroll?: boolean; | ||
| safeAreaInsetBottom?: boolean; | ||
| } | ||
| export type PopupInstanceType = { | ||
| popupRef: React.RefObject<HTMLDivElement>; | ||
| }; |
| export {}; |
| @import './var.less'; | ||
| :root { | ||
| --easy-popup-border-radius: @popup-border-radius; | ||
| --easy-popup-wrapper-background-color: @popup-wrapper-background-color; | ||
| --easy-popup-title-color: var(--func-text-dark-primary); | ||
| --easy-popup-title-font: var(--func-body-b3-b); | ||
| --easy-popup-content-text-color: var(--func-text-dark-secondary); | ||
| } | ||
| @keyframes overlay-fade-in { | ||
| from { | ||
| opacity: 0; | ||
| } | ||
| to { | ||
| opacity: 1; | ||
| } | ||
| } | ||
| @keyframes overlay-fade-out { | ||
| from { | ||
| opacity: 1; | ||
| } | ||
| to { | ||
| opacity: 0; | ||
| } | ||
| } | ||
| @keyframes slide-down-enter { | ||
| from { | ||
| transform: translate3d(0, 100%, 0); | ||
| } | ||
| } | ||
| @keyframes slide-up-enter { | ||
| from { | ||
| transform: translate3d(0, -100%, 0); | ||
| } | ||
| } | ||
| @keyframes center-fade-in { | ||
| from { | ||
| opacity: 0; | ||
| transform: translate3d(-50%, -50%, 0) scale(0.8); | ||
| } | ||
| to { | ||
| opacity: 1; | ||
| transform: translate3d(-50%, -50%, 0) scale(1); | ||
| } | ||
| } | ||
| @keyframes center-fade-out { | ||
| from { | ||
| opacity: 1; | ||
| transform: translate3d(-50%, -50%, 0) scale(1); | ||
| } | ||
| to { | ||
| opacity: 0; | ||
| transform: translate3d(-50%, -50%, 0) scale(0.8); | ||
| } | ||
| } | ||
| @keyframes rv-fade-out { | ||
| from { | ||
| opacity: 1; | ||
| } | ||
| to { | ||
| opacity: 0; | ||
| } | ||
| } | ||
| .@{prefix}-popupV2 { | ||
| &__container { | ||
| position: fixed; | ||
| inset: 0; | ||
| z-index: 1001; | ||
| pointer-events: none; | ||
| &--hidden { | ||
| display: none; | ||
| } | ||
| } | ||
| &__wrapper { | ||
| background: var(--easy-popup-wrapper-background-color); | ||
| transition: | ||
| transform 0.3s ease-in-out, | ||
| opacity 0.3s ease-in-out; | ||
| box-sizing: border-box; | ||
| max-height: 100%; | ||
| display: flex; | ||
| flex-direction: column; | ||
| pointer-events: auto; | ||
| &--bottom { | ||
| position: fixed; | ||
| bottom: 0; | ||
| left: 0; | ||
| width: 100%; | ||
| min-height: 45vh; | ||
| max-height: 60vh; | ||
| padding-bottom: 20 * @hd; | ||
| transform: translateY(100%); | ||
| border-top-left-radius: var(--easy-popup-border-radius); | ||
| border-top-right-radius: var(--easy-popup-border-radius); | ||
| .@{prefix}-popupV2__content { | ||
| padding: 0 15 * @hd; | ||
| color: var(--easy-popup-content-text-color); | ||
| } | ||
| /* stylelint-disable function-no-unknown */ | ||
| // 安全区域适配 | ||
| &.@{prefix}-popupV2__wrapper--safe-area-inset-bottom { | ||
| padding-bottom: calc(15 * @hd + constant(safe-area-inset-bottom)); | ||
| padding-bottom: calc(15 * @hd + env(safe-area-inset-bottom)); | ||
| } | ||
| } | ||
| &--center { | ||
| position: fixed; | ||
| top: 50%; | ||
| left: 50%; | ||
| transform: translate3d(-50%, -50%, 0) scale(1); | ||
| opacity: 0; | ||
| border-radius: var(--easy-popup-border-radius); | ||
| // 安全区域适配(center 位置通常不需要,但为了完整性) | ||
| &.@{prefix}-popupV2__wrapper--safe-area-inset-bottom { | ||
| padding-bottom: constant(safe-area-inset-bottom); | ||
| padding-bottom: env(safe-area-inset-bottom); | ||
| } | ||
| } | ||
| &--visible { | ||
| &.@{prefix}-popupV2__wrapper--bottom { | ||
| transform: translateY(0); | ||
| animation: slide-down-enter 0.3s ease-in-out 1 normal; | ||
| } | ||
| &.@{prefix}-popupV2__wrapper--center { | ||
| opacity: 1; | ||
| transform: translate3d(-50%, -50%, 0) scale(1); | ||
| animation: center-fade-in 0.3s ease-in-out 1 normal; | ||
| } | ||
| } | ||
| } | ||
| &__wrapper--bottom:not(&__wrapper--visible) { | ||
| animation: slide-down-exit 0.3s ease-in-out 1 normal; | ||
| } | ||
| &__wrapper--center:not(&__wrapper--visible) { | ||
| animation: center-fade-out 0.3s ease-in-out 1 normal; | ||
| } | ||
| &__header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| position: relative; | ||
| height: 64 * @hd; | ||
| padding: 15 * @hd; | ||
| text-align: left; | ||
| font: var(--easy-popup-title-font); | ||
| color: var(--easy-popup-title-color); | ||
| box-sizing: border-box; | ||
| background: linear-gradient(180deg, #d8ffdf 0%, #fff 100%); | ||
| .@{prefix}-popupV2__wrapper--bottom & { | ||
| border-top-left-radius: var(--easy-popup-border-radius); | ||
| border-top-right-radius: var(--easy-popup-border-radius); | ||
| } | ||
| .@{prefix}-popupV2__wrapper--center & { | ||
| border-top-left-radius: var(--easy-popup-border-radius); | ||
| border-top-right-radius: var(--easy-popup-border-radius); | ||
| padding-top: 20 * @hd; | ||
| } | ||
| } | ||
| &__title { | ||
| flex: 1; | ||
| // padding-right: 40 * @hd; | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| word-break: break-word; | ||
| } | ||
| &__close { | ||
| // position: absolute; | ||
| // right: 17 * @hd; | ||
| // top: 18 * @hd; | ||
| width: 24 * @hd; | ||
| height: 24 * @hd; | ||
| margin-left: 16 * @hd; | ||
| z-index: 1; | ||
| .@{prefix}-popupV2__wrapper--center & { | ||
| top: 12 * @hd; | ||
| right: 12 * @hd; | ||
| } | ||
| } | ||
| &__content { | ||
| overflow-y: auto; | ||
| display: flex; | ||
| flex-direction: column; | ||
| flex: 1; | ||
| min-height: 0; | ||
| .@{prefix}-popupV2__wrapper--center & { | ||
| max-height: calc(100% - 140px); | ||
| } | ||
| } | ||
| &__footer { | ||
| padding: 20 * @hd 15 * @hd 0; | ||
| } | ||
| &__button { | ||
| box-sizing: border-box; | ||
| width: 100%; | ||
| } | ||
| &__buttons { | ||
| display: flex; | ||
| justify-content: space-between; | ||
| &--button { | ||
| box-sizing: border-box; | ||
| width: 100%; | ||
| } | ||
| &--primary { | ||
| margin-left: 10 * @hd; | ||
| } | ||
| } | ||
| &__tip { | ||
| margin-top: 12 * @hd; | ||
| text-align: center; | ||
| color: var(--func-text-dark-secondary); | ||
| font: var(--func-body-b4-r); | ||
| } | ||
| } |
| @import '../../styles/var.less'; | ||
| @popup-border-radius: 16 * @hd; | ||
| @popup-wrapper-background-color: @white; | ||
| @popup-title-font-size: 16 * @hd; | ||
| @popup-title-font-weight: 700; | ||
| @popup-title-color: @dark-black; | ||
| @popup-main-color: @dark-black; | ||
| @popup-sub-color: @dark-gray; |
| import React from 'react'; | ||
| import { StrokeProps } from './PropsType'; | ||
| import './style/index.less'; | ||
| declare const Stroke: React.FC<StrokeProps>; | ||
| export default Stroke; |
| import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
| import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
| import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; | ||
| import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
| var _excluded = ["className", "type", "style", "color", "width", "customStyle", "children"]; | ||
| import clsx from 'clsx'; | ||
| import React from 'react'; | ||
| import { createNamespace } from "../utils"; | ||
| import { getWidthValue } from "../utils/getWidth"; | ||
| import "./style/index.less"; | ||
| import { jsx as _jsx } from "react/jsx-runtime"; | ||
| var _createNamespace = createNamespace('stroke'), | ||
| _createNamespace2 = _slicedToArray(_createNamespace, 1), | ||
| bem = _createNamespace2[0]; | ||
| // 根据类型获取对应的颜色 - 移到组件外部提升性能 | ||
| var getTypeColor = function getTypeColor(type) { | ||
| var colorMap = { | ||
| light: '--func-stroke-light', | ||
| grey: '--func-stroke-grey', | ||
| dark: '--func-stroke-dark', | ||
| green: '--func-stroke-green' | ||
| }; | ||
| return colorMap[type]; | ||
| }; | ||
| var Stroke = function Stroke(_ref) { | ||
| var className = _ref.className, | ||
| _ref$type = _ref.type, | ||
| type = _ref$type === void 0 ? 'light' : _ref$type, | ||
| _ref$style = _ref.style, | ||
| strokeStyle = _ref$style === void 0 ? 'solid' : _ref$style, | ||
| color = _ref.color, | ||
| _ref$width = _ref.width, | ||
| width = _ref$width === void 0 ? 1 : _ref$width, | ||
| customStyle = _ref.customStyle, | ||
| children = _ref.children, | ||
| restProps = _objectWithoutProperties(_ref, _excluded); | ||
| var strokeClasses = clsx(bem('', _defineProperty(_defineProperty({}, "".concat(type), true), "".concat(strokeStyle), true)), className); | ||
| var strokeColor = color ? color.includes('--') ? "var(".concat(color, ")") : color : "var(".concat(getTypeColor(type), ")"); | ||
| var combinedStyle = _objectSpread({ | ||
| borderColor: strokeColor, | ||
| borderWidth: getWidthValue(width), | ||
| borderStyle: strokeStyle | ||
| }, customStyle); | ||
| // 如果没有内容,渲染为一条水平线 | ||
| if (!children) { | ||
| return /*#__PURE__*/_jsx("div", _objectSpread({ | ||
| className: strokeClasses, | ||
| style: _objectSpread(_objectSpread({}, combinedStyle), {}, { | ||
| borderTop: 'none', | ||
| borderLeft: 'none', | ||
| borderRight: 'none', | ||
| borderBottomWidth: getWidthValue(width), | ||
| borderBottomStyle: strokeStyle, | ||
| borderBottomColor: strokeColor, | ||
| height: 0, | ||
| width: '100%' | ||
| }) | ||
| }, restProps)); | ||
| } | ||
| return /*#__PURE__*/_jsx("div", _objectSpread(_objectSpread({ | ||
| className: strokeClasses, | ||
| style: combinedStyle | ||
| }, restProps), {}, { | ||
| children: children | ||
| })); | ||
| }; | ||
| export default Stroke; |
| import React from 'react'; | ||
| export interface StrokeProps { | ||
| className?: string; | ||
| type?: 'light' | 'grey' | 'dark' | 'green'; | ||
| style?: 'solid' | 'dashed' | 'dotted'; | ||
| color?: string; | ||
| width?: number | string; | ||
| customStyle?: React.CSSProperties; | ||
| children?: React.ReactNode; | ||
| } |
| export {}; |
| @import '../../styles/var.less'; | ||
| .@{prefix}-stroke { | ||
| display: block; | ||
| border: 1px solid; | ||
| // 描边类型 - 颜色主题 | ||
| &--light { | ||
| border-color: var(--func-stroke-light); | ||
| } | ||
| &--grey { | ||
| border-color: var(--func-stroke-grey); | ||
| } | ||
| &--dark { | ||
| border-color: var(--func-stroke-dark); | ||
| } | ||
| &--green { | ||
| border-color: var(--func-stroke-green); | ||
| } | ||
| // 描边样式 | ||
| &--solid { | ||
| border-style: solid; | ||
| } | ||
| &--dashed { | ||
| border-style: dashed; | ||
| } | ||
| &--dotted { | ||
| border-style: dotted; | ||
| } | ||
| } |
| import React from 'react'; | ||
| import { TagProps } from './PropsType'; | ||
| import './style/index.less'; | ||
| declare const Tag: React.FC<TagProps>; | ||
| export default Tag; |
| import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
| import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
| import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
| import clsx from 'clsx'; | ||
| import React from 'react'; | ||
| import { createNamespace } from "../utils"; | ||
| import "./style/index.less"; | ||
| import { jsx as _jsx } from "react/jsx-runtime"; | ||
| import { jsxs as _jsxs } from "react/jsx-runtime"; | ||
| var _createNamespace = createNamespace('tag'), | ||
| _createNamespace2 = _slicedToArray(_createNamespace, 1), | ||
| bem = _createNamespace2[0]; | ||
| var Tag = function Tag(props) { | ||
| var className = props.className, | ||
| style = props.style, | ||
| _props$type = props.type, | ||
| type = _props$type === void 0 ? 'round' : _props$type, | ||
| icon = props.icon, | ||
| color = props.color, | ||
| backgroundColor = props.backgroundColor, | ||
| borderColor = props.borderColor, | ||
| children = props.children, | ||
| onClick = props.onClick; | ||
| var handleClick = function handleClick(e) { | ||
| onClick === null || onClick === void 0 || onClick(e); | ||
| }; | ||
| var renderIcon = function renderIcon() { | ||
| if (!icon) return null; | ||
| return /*#__PURE__*/_jsx("span", { | ||
| className: clsx(bem('icon')), | ||
| children: icon | ||
| }); | ||
| }; | ||
| var getCustomStyle = function getCustomStyle() { | ||
| return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, style), color && { | ||
| color: color | ||
| }), backgroundColor && { | ||
| background: backgroundColor | ||
| }), borderColor && { | ||
| borderColor: borderColor | ||
| }); | ||
| }; | ||
| return /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(bem('', _defineProperty({}, type, true)), className), | ||
| style: getCustomStyle(), | ||
| onClick: handleClick, | ||
| children: [renderIcon(), /*#__PURE__*/_jsx("span", { | ||
| className: clsx(bem('text')), | ||
| children: children | ||
| })] | ||
| }); | ||
| }; | ||
| export default Tag; |
| import React from 'react'; | ||
| export interface TagProps { | ||
| className?: string; | ||
| style?: React.CSSProperties; | ||
| type?: 'round' | 'slant'; | ||
| icon?: React.ReactNode | null; | ||
| color?: string; | ||
| backgroundColor?: string; | ||
| borderColor?: string; | ||
| children?: React.ReactNode; | ||
| onClick?: (e: React.MouseEvent) => void; | ||
| } |
| export {}; |
| @import './var.less'; | ||
| :root { | ||
| --easy-tag-padding: @tag-padding; | ||
| --easy-tag-font-size: @tag-font-size; | ||
| --easy-tag-line-height: @tag-line-height; | ||
| --easy-tag-height: @tag-height; | ||
| --easy-tag-gap: @tag-gap; | ||
| --easy-tag-icon-size: @tag-icon-size; | ||
| --easy-tag-border-radius-round: @tag-border-radius-round; | ||
| --easy-tag-border-radius-slant: @tag-border-radius-slant; | ||
| } | ||
| .@{prefix}-tag { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: var(--easy-tag-padding); | ||
| min-width: 52px; | ||
| max-width: 157px; | ||
| height: var(--easy-tag-height); | ||
| font-size: var(--easy-tag-font-size); | ||
| line-height: var(--easy-tag-line-height); | ||
| font-weight: 500; | ||
| border: 0.5px solid transparent; | ||
| box-sizing: border-box; | ||
| cursor: pointer; | ||
| user-select: none; | ||
| // round 类型 - 四个圆角 | ||
| &--round { | ||
| border-radius: var(--easy-tag-border-radius-round); | ||
| } | ||
| // slant 类型 - 斜角圆角(左上右下直角,右上左下圆角) | ||
| &--slant { | ||
| border-radius: var(--easy-tag-border-radius-slant); | ||
| } | ||
| // 图标(固定尺寸) | ||
| &__icon { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-size: var(--easy-tag-icon-size); | ||
| line-height: 1; | ||
| flex-shrink: 0; | ||
| margin-right: var(--easy-tag-gap); | ||
| img, | ||
| svg { | ||
| width: var(--easy-tag-icon-size); | ||
| height: var(--easy-tag-icon-size); | ||
| display: block; | ||
| } | ||
| } | ||
| // 文本内容 | ||
| &__text { | ||
| display: inline-block; | ||
| font: var(--func-caption-c2-s); | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| max-width: 100%; | ||
| } | ||
| } |
| @import '../../styles/var.less'; | ||
| // Tag 基础变量(固定不可变) | ||
| @tag-padding: 4 * @hd; | ||
| @tag-font-size: 12 * @hd; | ||
| @tag-line-height: 20 * @hd; | ||
| @tag-height: 18 * @hd; | ||
| @tag-gap: 2 * @hd; // 图标与文字间距 | ||
| @tag-icon-size: 12 * @hd; // 图标固定大小 | ||
| // Tag 圆角变量 | ||
| @tag-border-radius-round: 4 * @hd; // round 类型 - 四个圆角 | ||
| @tag-border-radius-slant: 0 8 * @hd 0 8 * @hd; // slant 类型 - 斜角圆角(左上右下直角,右上左下圆角) |
| import React from 'react'; | ||
| import { TextProps } from './PropsType'; | ||
| import './style/index.less'; | ||
| declare const Text: React.FC<TextProps>; | ||
| export default Text; |
| import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
| import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
| import clsx from 'clsx'; | ||
| import React from 'react'; | ||
| import { createNamespace } from "../utils"; | ||
| import { getWidthValue } from "../utils/getWidth"; | ||
| import "./style/index.less"; | ||
| import { jsx as _jsx } from "react/jsx-runtime"; | ||
| var _createNamespace = createNamespace('text'), | ||
| _createNamespace2 = _slicedToArray(_createNamespace, 1), | ||
| bem = _createNamespace2[0]; | ||
| var Text = function Text(_ref) { | ||
| var _ref$as = _ref.as, | ||
| Component = _ref$as === void 0 ? 'span' : _ref$as, | ||
| _ref$variant = _ref.variant, | ||
| variant = _ref$variant === void 0 ? 'func-body-b4-r' : _ref$variant, | ||
| _ref$color = _ref.color, | ||
| color = _ref$color === void 0 ? '--base-grey-black' : _ref$color, | ||
| _ref$align = _ref.align, | ||
| align = _ref$align === void 0 ? 'left' : _ref$align, | ||
| _ref$lines = _ref.lines, | ||
| lines = _ref$lines === void 0 ? 1 : _ref$lines, | ||
| _ref$width = _ref.width, | ||
| width = _ref$width === void 0 ? '100%' : _ref$width, | ||
| className = _ref.className, | ||
| style = _ref.style, | ||
| children = _ref.children; | ||
| return /*#__PURE__*/_jsx(Component, { | ||
| className: clsx(bem(''), className), | ||
| style: _objectSpread({ | ||
| WebkitLineClamp: lines, | ||
| textAlign: align, | ||
| color: color.includes('--') ? "var(".concat(color, ")") : color, | ||
| font: "var(".concat(variant, ")"), | ||
| width: getWidthValue(width) | ||
| }, style), | ||
| children: children | ||
| }); | ||
| }; | ||
| export default Text; |
| import React from 'react'; | ||
| export interface TextProps { | ||
| as?: keyof JSX.IntrinsicElements; | ||
| variant?: string; | ||
| color?: string; | ||
| align?: 'left' | 'center' | 'right'; | ||
| lines?: number; | ||
| width?: string | number; | ||
| className?: string; | ||
| style?: React.CSSProperties; | ||
| children: React.ReactNode; | ||
| } |
| export {}; |
| @import '../../styles/var.less'; | ||
| .@{prefix}-text { | ||
| display: -webkit-box; | ||
| -webkit-box-orient: vertical; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| word-break: break-word; | ||
| color: var(--easy-color-text-primary); | ||
| width: 100%; // 默认宽度,确保省略逻辑生效 | ||
| } |
| export declare const getWidthValue: (width: number | string) => string; |
| export var getWidthValue = function getWidthValue(width) { | ||
| if (typeof width === 'number') { | ||
| return "".concat(width, "px"); | ||
| } | ||
| // 处理字符串情况,确保有单位 | ||
| return width.includes('px') || width.includes('%') || width.includes('em') || width.includes('rem') ? width : "".concat(width, "px"); | ||
| }; |
| interface DebouncedFunction<T extends (...args: any[]) => any> { | ||
| (...args: Parameters<T>): void; | ||
| cancel(): void; | ||
| flush(): void; | ||
| } | ||
| declare function useDebounce<T extends (...args: any[]) => any>(callback: T, delay: number, immediate?: boolean): DebouncedFunction<T>; | ||
| export default useDebounce; |
| import { useCallback, useRef } from 'react'; | ||
| function useDebounce(callback, delay) { | ||
| var immediate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; | ||
| var timeoutRef = useRef(null); | ||
| var lastArgsRef = useRef(null); | ||
| var debounced = useCallback(function () { | ||
| var context = this; | ||
| for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
| args[_key] = arguments[_key]; | ||
| } | ||
| lastArgsRef.current = args; | ||
| var later = function later() { | ||
| timeoutRef.current = null; | ||
| if (!immediate) { | ||
| callback.apply(context, lastArgsRef.current); | ||
| } | ||
| }; | ||
| var callNow = immediate && !timeoutRef.current; | ||
| if (timeoutRef.current) { | ||
| clearTimeout(timeoutRef.current); | ||
| } | ||
| timeoutRef.current = setTimeout(later, delay); | ||
| if (callNow) { | ||
| callback.apply(context, args); | ||
| } | ||
| }, [callback, delay, immediate]); | ||
| debounced.cancel = useCallback(function () { | ||
| if (timeoutRef.current) { | ||
| clearTimeout(timeoutRef.current); | ||
| timeoutRef.current = null; | ||
| } | ||
| }, []); | ||
| debounced.flush = useCallback(function () { | ||
| if (timeoutRef.current && lastArgsRef.current) { | ||
| clearTimeout(timeoutRef.current); | ||
| timeoutRef.current = null; | ||
| callback.apply(debounced, lastArgsRef.current); | ||
| } | ||
| }, [callback, debounced]); | ||
| return debounced; | ||
| } | ||
| export default useDebounce; |
@@ -7,2 +7,3 @@ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
| import { createNamespace } from "../utils"; | ||
| import useDebounce from "../utils/hooks/useDebounce"; | ||
| import "./style/index.less"; | ||
@@ -24,3 +25,9 @@ import { jsx as _jsx } from "react/jsx-runtime"; | ||
| onClick = _ref.onClick, | ||
| children = _ref.children; | ||
| children = _ref.children, | ||
| _ref$needDebounce = _ref.needDebounce, | ||
| needDebounce = _ref$needDebounce === void 0 ? false : _ref$needDebounce, | ||
| _ref$debounceTime = _ref.debounceTime, | ||
| debounceTime = _ref$debounceTime === void 0 ? 500 : _ref$debounceTime, | ||
| _ref$immediate = _ref.immediate, | ||
| immediate = _ref$immediate === void 0 ? true : _ref$immediate; | ||
| var buttonClasses = clsx(className, bem('', _defineProperty(_defineProperty(_defineProperty({ | ||
@@ -30,2 +37,4 @@ disabled: disabled, | ||
| }, "".concat(size), true), "".concat(status), true), "text", isTextButton))); | ||
| // 普通点击事件 | ||
| var handleClick = function handleClick(event) { | ||
@@ -36,5 +45,10 @@ if (!disabled) { | ||
| }; | ||
| // 防抖点击事件 | ||
| var handleDebounceClick = useDebounce(function (event) { | ||
| handleClick(event); | ||
| }, debounceTime, immediate); | ||
| return /*#__PURE__*/_jsx("div", { | ||
| className: buttonClasses, | ||
| onClick: handleClick, | ||
| onClick: needDebounce ? handleDebounceClick : handleClick, | ||
| "aria-disabled": disabled, | ||
@@ -41,0 +55,0 @@ role: "button", |
@@ -10,2 +10,5 @@ import React from 'react'; | ||
| children?: React.ReactNode; | ||
| needDebounce?: boolean; | ||
| debounceTime?: number; | ||
| immediate?: boolean; | ||
| } |
@@ -6,5 +6,7 @@ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
| import Button from "../button"; | ||
| import ButtonV2 from "../button-v2"; | ||
| import Overlay from "../overlay"; | ||
| import { createNamespace } from "../utils"; | ||
| import { mergeProps } from "../utils/getDefaultProps"; | ||
| import Close from "./icon/close.png"; | ||
| import Close from "./icon/close.svg"; | ||
| import { jsx as _jsx } from "react/jsx-runtime"; | ||
@@ -30,3 +32,3 @@ import { jsxs as _jsxs } from "react/jsx-runtime"; | ||
| return /*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('header', { | ||
| className: clsx(props.headerAlign ? bem('header', _defineProperty(_defineProperty({}, props.headerAlign, props.headerAlign), "isolated", !props.message && !props.children)) : bem('header', { | ||
| isolated: !props.message && !props.children | ||
@@ -41,2 +43,8 @@ })), | ||
| if (props.showClose) { | ||
| if (props.closeIcon) { | ||
| return /*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('icon')), | ||
| children: props.closeIcon | ||
| }); | ||
| } | ||
| return /*#__PURE__*/_jsx("img", { | ||
@@ -65,7 +73,4 @@ onClick: function onClick(e) { | ||
| return /*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('content')), | ||
| children: /*#__PURE__*/_jsx("div", { | ||
| className: clsx(messageAlign ? bem('message', _defineProperty({}, messageAlign, messageAlign)) : bem('message')), | ||
| children: message | ||
| }) | ||
| className: clsx(messageAlign ? bem('message', _defineProperty({}, messageAlign, messageAlign)) : bem('message')), | ||
| children: message | ||
| }); | ||
@@ -76,28 +81,63 @@ } | ||
| var renderButtons = function renderButtons() { | ||
| var _props$cancelProps, _props$confirmProps; | ||
| var _props$confirmProps2, _props$cancelProps2; | ||
| if (!props.showCancelButton && !props.showConfirmButton) { | ||
| return null; | ||
| } | ||
| if (props.buttonsInOneLine) { | ||
| var _props$cancelProps, _props$confirmProps; | ||
| return /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(bem('footer_same_line')), | ||
| children: [props.showCancelButton && /*#__PURE__*/_jsx(ButtonV2, { | ||
| theme: "green", | ||
| type: "secondary", | ||
| state: "normal", | ||
| className: clsx(bem('cancel_same_line')), | ||
| disabled: (_props$cancelProps = props.cancelProps) === null || _props$cancelProps === void 0 ? void 0 : _props$cancelProps.disabled, | ||
| onClick: function onClick(e) { | ||
| var _props$onCancel, _props$onClosed2; | ||
| e === null || e === void 0 || e.stopPropagation(); | ||
| props === null || props === void 0 || (_props$onCancel = props.onCancel) === null || _props$onCancel === void 0 || _props$onCancel.call(props, e); | ||
| props === null || props === void 0 || (_props$onClosed2 = props.onClosed) === null || _props$onClosed2 === void 0 || _props$onClosed2.call(props); | ||
| }, | ||
| children: props.cancelButtonText | ||
| }), props.showConfirmButton && /*#__PURE__*/_jsx(Button, { | ||
| size: "large", | ||
| status: "active", | ||
| className: clsx(bem('confirm_same_line')), | ||
| disabled: (_props$confirmProps = props.confirmProps) === null || _props$confirmProps === void 0 ? void 0 : _props$confirmProps.disabled, | ||
| onClick: function onClick(e) { | ||
| var _props$onConfirm, _props$onClosed3; | ||
| e === null || e === void 0 || e.stopPropagation(); | ||
| (_props$onConfirm = props.onConfirm) === null || _props$onConfirm === void 0 || _props$onConfirm.call(props, e); | ||
| (_props$onClosed3 = props.onClosed) === null || _props$onClosed3 === void 0 || _props$onClosed3.call(props); | ||
| }, | ||
| children: props.confirmButtonText | ||
| })] | ||
| }); | ||
| } | ||
| return /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(bem('footer')), | ||
| children: [props.showCancelButton && /*#__PURE__*/_jsx(Button, { | ||
| children: [props.showConfirmButton && /*#__PURE__*/_jsx(Button, { | ||
| size: "large", | ||
| className: clsx(bem('cancel')), | ||
| isTextButton: true, | ||
| disabled: (_props$cancelProps = props.cancelProps) === null || _props$cancelProps === void 0 ? void 0 : _props$cancelProps.disabled, | ||
| status: "active", | ||
| className: clsx(bem('confirm')), | ||
| disabled: (_props$confirmProps2 = props.confirmProps) === null || _props$confirmProps2 === void 0 ? void 0 : _props$confirmProps2.disabled, | ||
| onClick: function onClick(e) { | ||
| var _props$onCancel, _props$onClosed2; | ||
| (_props$onCancel = props.onCancel) === null || _props$onCancel === void 0 || _props$onCancel.call(props, e); | ||
| (_props$onClosed2 = props.onClosed) === null || _props$onClosed2 === void 0 || _props$onClosed2.call(props); | ||
| var _props$onConfirm2, _props$onClosed4; | ||
| (_props$onConfirm2 = props.onConfirm) === null || _props$onConfirm2 === void 0 || _props$onConfirm2.call(props, e); | ||
| (_props$onClosed4 = props.onClosed) === null || _props$onClosed4 === void 0 || _props$onClosed4.call(props); | ||
| }, | ||
| children: props.cancelButtonText | ||
| }), props.showConfirmButton && /*#__PURE__*/_jsx(Button, { | ||
| children: props.confirmButtonText | ||
| }), props.showCancelButton && /*#__PURE__*/_jsx(Button, { | ||
| size: "large", | ||
| status: "active", | ||
| className: clsx(bem('cancel')), | ||
| isTextButton: true, | ||
| className: clsx(bem('confirm')), | ||
| disabled: (_props$confirmProps = props.confirmProps) === null || _props$confirmProps === void 0 ? void 0 : _props$confirmProps.disabled, | ||
| disabled: (_props$cancelProps2 = props.cancelProps) === null || _props$cancelProps2 === void 0 ? void 0 : _props$cancelProps2.disabled, | ||
| onClick: function onClick(e) { | ||
| var _props$onConfirm, _props$onClosed3; | ||
| (_props$onConfirm = props.onConfirm) === null || _props$onConfirm === void 0 || _props$onConfirm.call(props, e); | ||
| (_props$onClosed3 = props.onClosed) === null || _props$onClosed3 === void 0 || _props$onClosed3.call(props); | ||
| var _props$onCancel2, _props$onClosed5; | ||
| (_props$onCancel2 = props.onCancel) === null || _props$onCancel2 === void 0 || _props$onCancel2.call(props, e); | ||
| (_props$onClosed5 = props.onClosed) === null || _props$onClosed5 === void 0 || _props$onClosed5.call(props); | ||
| }, | ||
| children: props.confirmButtonText | ||
| children: props.cancelButtonText | ||
| })] | ||
@@ -110,9 +150,22 @@ }); | ||
| }; | ||
| var handleClickOverlay = function handleClickOverlay(e) { | ||
| if (props.closeOnClickOverlay) { | ||
| var _props$onClosed6; | ||
| e === null || e === void 0 || e.stopPropagation(); | ||
| onClickCloseIcon === null || onClickCloseIcon === void 0 || onClickCloseIcon(); | ||
| props === null || props === void 0 || (_props$onClosed6 = props.onClosed) === null || _props$onClosed6 === void 0 || _props$onClosed6.call(props); | ||
| } | ||
| }; | ||
| if (!props.visible) return null; | ||
| return /*#__PURE__*/_jsxs("div", { | ||
| className: clsx(bem('container')), | ||
| children: [/*#__PURE__*/_jsx("div", { | ||
| className: clsx(bem('overlay', { | ||
| visible: visible | ||
| })) | ||
| children: [/*#__PURE__*/_jsx(Overlay, { | ||
| visible: true, | ||
| style: { | ||
| zIndex: 0 | ||
| }, | ||
| className: props.overlayClass, | ||
| onClick: handleClickOverlay, | ||
| frostedGlass: props.frostedGlass, | ||
| lockScroll: props.lockScroll | ||
| }), /*#__PURE__*/_jsxs("div", { | ||
@@ -119,0 +172,0 @@ className: clsx(bem('wrapper', { |
@@ -12,4 +12,3 @@ import React from 'react'; | ||
| title?: string | React.ReactNode; | ||
| theme?: string; | ||
| width?: string | number; | ||
| headerAlign?: 'center' | 'right'; | ||
| message?: React.ReactNode; | ||
@@ -20,11 +19,10 @@ transition?: string; | ||
| cancelButtonText?: React.ReactNode; | ||
| cancelButtonColor?: string; | ||
| showConfirmButton?: boolean; | ||
| confirmButtonText?: React.ReactNode; | ||
| confirmButtonColor?: string; | ||
| overlay?: boolean; | ||
| buttonsInOneLine?: boolean; | ||
| overlayClass?: string; | ||
| overlayStyle?: React.CSSProperties; | ||
| closeOnPopstate?: boolean; | ||
| closeOnClickOverlay?: boolean; | ||
| lockScroll?: boolean; | ||
| frostedGlass?: boolean; | ||
| onClickCloseIcon?: () => void; | ||
@@ -31,0 +29,0 @@ children?: React.ReactNode; |
@@ -5,2 +5,4 @@ @import './var.less'; | ||
| --easy-dialog-width: @dialog-width; | ||
| --easy-dialog-min-height: @dialog-min-height; | ||
| --easy-dialog-max-height: @dialog-max-height; | ||
| --easy-dialog-small-screen-width: @dialog-small-screen-width; | ||
@@ -24,2 +26,3 @@ --easy-dialog-font-size: @dialog-font-size; | ||
| --easy-dialog-confirm-button-text-color: @dialog-confirm-button-text-color; | ||
| --easy-dialog-message-font-weight: @dialog-message-font-weight; | ||
| } | ||
@@ -34,16 +37,5 @@ | ||
| &__overlay { | ||
| position: absolute; | ||
| inset: 0; | ||
| background: rgba(0, 0, 0, 0.6); | ||
| opacity: 0; | ||
| transition: opacity 0.3s ease-in-out; | ||
| &--visible { | ||
| opacity: 1; | ||
| animation: overlay-fade-in 0.3s ease-in-out 1 normal; | ||
| } | ||
| } | ||
| &__wrapper { | ||
| display: flex; | ||
| flex-direction: column; | ||
| position: fixed; | ||
@@ -53,5 +45,6 @@ top: 45%; | ||
| width: var(--easy-dialog-width); | ||
| min-height: var(--easy-dialog-min-height); | ||
| max-height: var(--easy-dialog-max-height); | ||
| overflow: hidden; | ||
| padding-top: 20 * @hd; | ||
| padding-bottom: 20 * @hd; | ||
| padding: 24 * @hd 16 * @hd 20 * @hd; | ||
| font-size: var(--easy-dialog-font-size); | ||
@@ -64,2 +57,3 @@ background-color: var(--easy-dialog-background-color); | ||
| opacity: 0; | ||
| box-sizing: border-box; | ||
@@ -72,9 +66,15 @@ &--visible { | ||
| &__icon { | ||
| position: absolute; | ||
| top: 8 * @hd; | ||
| right: 8 * @hd; | ||
| cursor: pointer; | ||
| } | ||
| &__close { | ||
| position: absolute; | ||
| width: 12 * @hd; | ||
| height: 12 * @hd; | ||
| top: 12 * @hd; | ||
| right: 12 * @hd; | ||
| margin-bottom: 20 * @hd; | ||
| width: 16 * @hd; | ||
| height: 16 * @hd; | ||
| top: 8 * @hd; | ||
| right: 8 * @hd; | ||
| cursor: pointer; | ||
@@ -84,6 +84,7 @@ } | ||
| &__header { | ||
| padding: 0 20 * @hd 20 * @hd; | ||
| flex-shrink: 0; | ||
| padding-bottom: 12 * @hd; | ||
| font-weight: 700; | ||
| line-height: var(--easy-dialog-header-line-height); | ||
| text-align: center; | ||
| text-align: left; | ||
| white-space: nowrap; | ||
@@ -96,2 +97,10 @@ overflow: hidden; | ||
| } | ||
| &--center { | ||
| text-align: center; | ||
| } | ||
| &--right { | ||
| text-align: right; | ||
| } | ||
| } | ||
@@ -101,7 +110,8 @@ | ||
| flex: 1; | ||
| max-height: var(--easy-dialog-message-max-height); | ||
| padding: 0 20 * @hd 20 * @hd; | ||
| overflow-y: auto; | ||
| min-height: 28 * @hd; | ||
| font-size: var(--easy-dialog-message-font-size); | ||
| line-height: var(--easy-dialog-message-line-height); | ||
| font-weight: var(--easy-dialog-message-font-weight); | ||
| color: var(--easy-dialog-message-text-color); | ||
@@ -128,27 +138,69 @@ // allow newline character | ||
| &__footer_same_line { | ||
| display: flex; | ||
| overflow: hidden; | ||
| user-select: none; | ||
| margin-top: 12 * @hd; | ||
| flex-shrink: 0; | ||
| } | ||
| &__cancel_same_line { | ||
| flex: 1; | ||
| } | ||
| &__confirm_same_line { | ||
| flex: 1; | ||
| display: block; | ||
| text-align: center; | ||
| padding: 16 * @hd; | ||
| border-radius: 28 * @hd; | ||
| background-color: @green; | ||
| color: @white; | ||
| font-weight: 700; | ||
| font-size: 16 * @hd; | ||
| line-height: 24 * @hd; | ||
| white-space: nowrap; | ||
| text-overflow: ellipsis; | ||
| overflow: hidden; | ||
| margin-left: 10px; | ||
| } | ||
| &__footer { | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| user-select: none; | ||
| border-top: 1 * @hd solid #dedede; | ||
| padding-top: 20 * @hd; | ||
| margin-top: 12 * @hd; | ||
| flex-shrink: 0; | ||
| } | ||
| &__confirm, | ||
| &__cancel { | ||
| &.@{prefix}-button { | ||
| flex: 1; | ||
| margin: 0; | ||
| border: 0; | ||
| padding: 0; | ||
| color: #ccc; | ||
| } | ||
| &__confirm { | ||
| display: block; | ||
| flex: 1; | ||
| text-align: center; | ||
| padding: 16 * @hd; | ||
| border-radius: 28 * @hd; | ||
| background-color: @green; | ||
| color: @white; | ||
| font-weight: 700; | ||
| font-size: 16 * @hd; | ||
| line-height: 24 * @hd; | ||
| white-space: nowrap; | ||
| text-overflow: ellipsis; | ||
| overflow: hidden; | ||
| } | ||
| &__confirm { | ||
| &, | ||
| &__cancel { | ||
| display: block; | ||
| flex: 1; | ||
| padding: 0; | ||
| margin-top: 10 * @hd; | ||
| text-align: center; | ||
| color: #666; | ||
| font-weight: 400; | ||
| font-size: 14 * @hd; | ||
| line-height: 20 * @hd; | ||
| &:active { | ||
| &.@{prefix}-button { | ||
| color: var(--easy-dialog-confirm-button-text-color); | ||
| } | ||
| color: #8992a1 !important; | ||
| } | ||
@@ -155,0 +207,0 @@ } |
@@ -14,9 +14,12 @@ @import '../../styles/var.less'; | ||
| --easy-primary-color: @green; | ||
| --easy-dialog-message-text-color: @light-black; | ||
| } | ||
| @dialog-width: 320 * @hd; | ||
| @dialog-min-height: 17vh; | ||
| @dialog-max-height: 45vh; | ||
| @dialog-small-screen-width: 90%; | ||
| @dialog-font-size: var(--easy-font-size-lg); | ||
| @dialog-transition: var(--easy-animation-duration-base); | ||
| @dialog-border-radius: 8 * @hd; | ||
| @dialog-border-radius: 12 * @hd; | ||
| @dialog-background-color: var(--easy-white); | ||
@@ -29,3 +32,4 @@ @dialog-header-font-weight: var(--easy-font-weight-bold); | ||
| @dialog-message-font-size: var(--easy-font-size-md); | ||
| @dialog-message-line-height: 16 * @hd; | ||
| @dialog-message-line-height: 20 * @hd; | ||
| @dialog-message-font-weight: 400; | ||
| @dialog-message-max-height: 160 * @hd; | ||
@@ -32,0 +36,0 @@ @dialog-has-title-message-text-color: var(--easy-gray-7); |
| export { default as Button } from './button'; | ||
| export { default as ButtonV2 } from './button-v2'; | ||
| export { default as ConfigProvider } from './config-provider'; | ||
| export { default as Dialog } from './dialog'; | ||
| export { default as Input } from './input'; | ||
| export { default as ListCell } from './listcell'; | ||
| export { default as Loading } from './loading'; | ||
@@ -9,4 +11,8 @@ export { default as Navbar } from './navbar'; | ||
| export { default as Popup } from './popup'; | ||
| export { default as PopupV2 } from './popup-v2'; | ||
| export { default as Stroke } from './stroke'; | ||
| export { default as Tabs } from './tabs'; | ||
| export { default as TabPane } from './tabs/tabPane'; | ||
| export { default as Tag } from './tag'; | ||
| export { default as Text } from './text'; | ||
| export { default as Toast } from './toast'; |
| export { default as Button } from "./button"; | ||
| export { default as ButtonV2 } from "./button-v2"; | ||
| export { default as ConfigProvider } from "./config-provider"; | ||
| export { default as Dialog } from "./dialog"; | ||
| export { default as Input } from "./input"; | ||
| export { default as ListCell } from "./listcell"; | ||
| export { default as Loading } from "./loading"; | ||
@@ -9,4 +11,8 @@ export { default as Navbar } from "./navbar"; | ||
| export { default as Popup } from "./popup"; | ||
| export { default as PopupV2 } from "./popup-v2"; | ||
| export { default as Stroke } from "./stroke"; | ||
| export { default as Tabs } from "./tabs"; | ||
| export { default as TabPane } from "./tabs/tabPane"; | ||
| export { default as Tag } from "./tag"; | ||
| export { default as Text } from "./text"; | ||
| export { default as Toast } from "./toast"; |
| import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
| import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
| import clsx from 'clsx'; | ||
| import React, { useEffect } from 'react'; | ||
| import React, { useEffect, useRef, useState } from 'react'; | ||
| import { createNamespace } from "../utils"; | ||
@@ -11,2 +11,12 @@ import "./style/index.less"; | ||
| bem = _createNamespace2[0]; | ||
| // 阻止事件默认行为 | ||
| var preventDefault = function preventDefault(event, isStopPropagation) { | ||
| if (typeof event.cancelable !== 'boolean' || event.cancelable) { | ||
| event.preventDefault(); | ||
| } | ||
| if (isStopPropagation) { | ||
| event.stopPropagation(); | ||
| } | ||
| }; | ||
| var Overlay = function Overlay(_ref) { | ||
@@ -21,37 +31,71 @@ var _ref$visible = _ref.visible, | ||
| style = _ref.style, | ||
| onClick = _ref.onClick, | ||
| _onClick = _ref.onClick, | ||
| children = _ref.children, | ||
| _ref$lockScroll = _ref.lockScroll, | ||
| lockScroll = _ref$lockScroll === void 0 ? true : _ref$lockScroll; | ||
| lockScroll = _ref$lockScroll === void 0 ? true : _ref$lockScroll, | ||
| _ref$frostedGlass = _ref.frostedGlass, | ||
| frostedGlass = _ref$frostedGlass === void 0 ? true : _ref$frostedGlass; | ||
| var _useState = useState(visible), | ||
| _useState2 = _slicedToArray(_useState, 2), | ||
| active = _useState2[0], | ||
| setActive = _useState2[1]; | ||
| var overlayRef = useRef(null); | ||
| // 阻止触摸滚动 | ||
| var preventTouchMove = function preventTouchMove(event) { | ||
| if (!lockScroll) return; | ||
| preventDefault(event, true); | ||
| }; | ||
| useEffect(function () { | ||
| if (lockScroll) { | ||
| if (visible) { | ||
| document.body.style.overflow = 'hidden'; | ||
| } else { | ||
| document.body.style.overflow = ''; | ||
| } | ||
| if (visible) { | ||
| setActive(true); | ||
| } else { | ||
| var timer = setTimeout(function () { | ||
| setActive(false); | ||
| }, duration); | ||
| return function () { | ||
| clearTimeout(timer); | ||
| }; | ||
| } | ||
| }, [visible, duration]); | ||
| // 监听 touchmove 事件阻止滚动 | ||
| useEffect(function () { | ||
| var node = overlayRef.current; | ||
| if (!node || !lockScroll) return; | ||
| node.addEventListener('touchmove', preventTouchMove, { | ||
| passive: false | ||
| }); | ||
| return function () { | ||
| if (lockScroll) { | ||
| document.body.style.overflow = ''; | ||
| } | ||
| node.removeEventListener('touchmove', preventTouchMove); | ||
| }; | ||
| }, [visible, lockScroll]); | ||
| }, [lockScroll]); | ||
| if (!active) return null; | ||
| var baseStyle = _objectSpread({ | ||
| zIndex: zIndex | ||
| zIndex: zIndex, | ||
| '--duration': "".concat(duration, "ms") | ||
| }, style); | ||
| if (duration) { | ||
| baseStyle.animationDuration = "".concat(duration, "ms"); | ||
| // 使用 touchAction 阻止触摸操作 | ||
| if (lockScroll) { | ||
| baseStyle.touchAction = 'none'; | ||
| } | ||
| return visible ? /*#__PURE__*/_jsx("div", { | ||
| return /*#__PURE__*/_jsx("div", { | ||
| ref: overlayRef, | ||
| role: "presentation", | ||
| className: clsx(bem('', { | ||
| visible: visible | ||
| visible: visible, | ||
| 'no-frosted-glass': !frostedGlass | ||
| }), className), | ||
| style: baseStyle, | ||
| onClick: onClick, | ||
| onClick: function onClick(e) { | ||
| // 只有点击遮罩层本身时才触发 onClick | ||
| if (e.target === e.currentTarget) { | ||
| _onClick === null || _onClick === void 0 || _onClick(e); | ||
| } | ||
| }, | ||
| "data-testid": "overlay", | ||
| children: children | ||
| }) : null; | ||
| }); | ||
| }; | ||
| export default Overlay; |
@@ -11,2 +11,3 @@ /// <reference types="react" /> | ||
| lockScroll?: boolean; | ||
| frostedGlass?: boolean; | ||
| } |
| @import '../../styles/var.less'; | ||
| .overlay { | ||
| .@{prefix}-overlay { | ||
| position: fixed; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background-color: rgba(0, 0, 0, 0.7); | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| @keyframes overlay-fade-in { | ||
| from { | ||
| opacity: 0; | ||
| visibility: hidden; | ||
| transition: | ||
| opacity var(--duration, 300ms) ease-in-out, | ||
| visibility var(--duration, 300ms) ease-in-out; | ||
| -webkit-tap-highlight-color: transparent; | ||
| } | ||
| &--visible { | ||
| to { | ||
| opacity: 1; | ||
| visibility: visible; | ||
| } | ||
| } | ||
| @keyframes overlay-fade-in { | ||
| from { | ||
| opacity: 0; | ||
| } | ||
| @keyframes overlay-fade-out { | ||
| from { | ||
| opacity: 1; | ||
| } | ||
| to { | ||
| opacity: 1; | ||
| } | ||
| to { | ||
| opacity: 0; | ||
| } | ||
| } | ||
| @keyframes overlay-fade-out { | ||
| from { | ||
| opacity: 1; | ||
| } | ||
| .@{prefix}-overlay { | ||
| position: fixed; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background-color: @overlay-blur-background-color; | ||
| backdrop-filter: blur(10px); | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| opacity: 0; | ||
| transition: opacity var(--duration, 300ms) ease-in-out; | ||
| -webkit-tap-highlight-color: transparent; | ||
| to { | ||
| opacity: 0; | ||
| } | ||
| // 不支持 backdrop-filter 的浏览器降级处理 | ||
| @supports not (backdrop-filter: blur(10px)) { | ||
| background-color: @overlay-background-color; | ||
| } | ||
| &--visible { | ||
| opacity: 1; | ||
| animation: overlay-fade-in var(--duration, 300ms) ease-in-out 1 normal; | ||
| } | ||
| // 遮罩层关闭动画 | ||
| &:not(&--visible) { | ||
| animation: overlay-fade-out var(--duration, 300ms) ease-in-out 1 normal; | ||
| } | ||
| // 关闭毛玻璃效果时的样式 | ||
| &--no-frosted-glass { | ||
| background-color: @overlay-background-color; | ||
| backdrop-filter: none; | ||
| } | ||
| } |
@@ -40,3 +40,5 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
| position = _props$position === void 0 ? 'center' : _props$position, | ||
| style = props.style; | ||
| style = props.style, | ||
| _props$frostedGlass = props.frostedGlass, | ||
| frostedGlass = _props$frostedGlass === void 0 ? true : _props$frostedGlass; | ||
| var _useState = useState(visible), | ||
@@ -154,3 +156,4 @@ _useState2 = _slicedToArray(_useState, 2), | ||
| className: clsx(bem('overlay', { | ||
| visible: visible | ||
| visible: visible, | ||
| 'no-frosted-glass': !frostedGlass | ||
| }), props.overlayClass), | ||
@@ -157,0 +160,0 @@ onClick: onClickOverlay |
@@ -24,2 +24,3 @@ /// <reference types="react" /> | ||
| onClickOverlay?: (e: React.MouseEvent) => void; | ||
| frostedGlass?: boolean; | ||
| } | ||
@@ -26,0 +27,0 @@ export type PopupInstanceType = { |
@@ -9,3 +9,2 @@ @import './var.less'; | ||
| --easy-popup-border-radius: @popup-border-radius; | ||
| --easy-popup-overlay-background-color: @popup-overlay-background-color; | ||
| --easy-popup-wrapper-background-color: @popup-wrapper-background-color; | ||
@@ -99,6 +98,12 @@ --easy-popup-title-font-size: @popup-title-font-size; | ||
| inset: 0; | ||
| background: var(--easy-popup-overlay-background-color); | ||
| background-color: @overlay-blur-background-color; | ||
| backdrop-filter: blur(10px); | ||
| opacity: 0; | ||
| transition: opacity 0.3s ease-in-out; | ||
| // 不支持 backdrop-filter 的浏览器降级处理 | ||
| @supports not (backdrop-filter: blur(10px)) { | ||
| background-color: @overlay-background-color; | ||
| } | ||
| &--visible { | ||
@@ -108,2 +113,8 @@ opacity: 1; | ||
| } | ||
| // 关闭毛玻璃效果时的样式 | ||
| &--no-frosted-glass { | ||
| background-color: @overlay-background-color; | ||
| backdrop-filter: none; | ||
| } | ||
| } | ||
@@ -110,0 +121,0 @@ |
| @import '../../styles/var.less'; | ||
| @popup-border-radius: 16 * @hd; | ||
| @popup-overlay-background-color: rgba(0, 0, 0, 0.6); | ||
| @popup-wrapper-background-color: @white; | ||
@@ -6,0 +5,0 @@ @popup-title-font-size: 16 * @hd; |
@@ -0,1 +1,3 @@ | ||
| @import '@yqg/design-tokens'; | ||
| // 基本单位 | ||
@@ -17,2 +19,5 @@ @hd: 1px; | ||
| // 模糊效果背景 | ||
| @overlay-background-color: rgba(0, 0, 0, 0.85); | ||
| @overlay-blur-background-color: rgba(0, 0, 0, 0.8); | ||
| // netural-color | ||
@@ -19,0 +24,0 @@ @white: #ffffff; |
@@ -57,3 +57,2 @@ @import './var.less'; | ||
| // https://github.com/youzan/vant/issues/8959 | ||
| word-break: break-all; | ||
| background-color: var(--easy-toast-background-color); | ||
@@ -60,0 +59,0 @@ border-radius: var(--easy-toast-border-radius); |
@@ -19,3 +19,3 @@ @import '../../styles/var.less'; | ||
| @toast-border-radius: var(--easy-border-radius-lg); | ||
| @toast-background-color: rgba(0, 0, 0, 0.7); | ||
| @toast-background-color: rgba(0, 0, 0, 0.8); | ||
| @toast-icon-size: 36 * @hd; | ||
@@ -22,0 +22,0 @@ @toast-text-min-width: 96 * @hd; |
+2
-1
| { | ||
| "name": "@yqg/easy-ui", | ||
| "version": "1.0.2", | ||
| "version": "2.0.0", | ||
| "license": "MIT", | ||
@@ -11,2 +11,3 @@ "main": "dist/esm/index.js", | ||
| "build": "max build --target=bundle", | ||
| "compress": "zip -qry build.zip dist && rm -rf dist && mv build.zip ../../", | ||
| "dev": "max dev --target=docs", | ||
@@ -13,0 +14,0 @@ "docs:build": "max build --target=docs", |
Sorry, the diff of this file is not supported yet
198690
85.3%148
39.62%2985
40.87%