From ab0489f6928aa534ec8c2a2271c9a0c3990e086e Mon Sep 17 00:00:00 2001 From: ZhangAo Date: Wed, 3 Sep 2025 17:31:30 +0800 Subject: [PATCH] u --- .../ao-design/src/_styles/_variables.scss | 126 +++++++++++++ .../packages/ao-design/src/_styles/index.scss | 3 + .../ao-design/src/_styles/theme/_dark.scss | 169 +++++++++++++++++ .../ao-design/src/_styles/theme/_font.scss | 70 ++++++++ .../ao-design/src/_styles/theme/_light.scss | 170 ++++++++++++++++++ .../ao-design/src/_styles/theme/_radius.scss | 10 ++ .../ao-design/src/_styles/theme/_size.scss | 19 ++ .../ao-design/src/_styles/theme/index.scss | 37 +++- .../packages/ao-design/src/button/index.scss | 161 +++++------------ .../packages/ao-design/src/components.ts | 1 + .../packages/ao-design/src/group/index.scss | 44 +++++ .../packages/ao-design/src/group/index.tsx | 17 ++ .../packages/ao-design/src/icon/index.scss | 13 +- .../packages/ao-design/src/icon/index.tsx | 15 +- .../packages/ao-design/src/index.scss | 1 + .../packages/ao-design/src/input/index.scss | 115 ++++-------- .../packages/ao-design/src/input/index.tsx | 55 ++---- .../packages/ao-design/src/spin/index.tsx | 3 +- .../ao-design/src/textarea/index.scss | 106 +++++++++-- .../packages/ao-design/src/textarea/index.tsx | 120 ++++++++++++- code/base-project/base-vue/src/App.vue | 143 ++++++++++++--- .../base-project/base-vue/src/components.d.ts | 2 + 22 files changed, 1100 insertions(+), 300 deletions(-) create mode 100644 code/base-project/base-vue/packages/ao-design/src/_styles/_variables.scss create mode 100644 code/base-project/base-vue/packages/ao-design/src/_styles/index.scss create mode 100644 code/base-project/base-vue/packages/ao-design/src/_styles/theme/_dark.scss create mode 100644 code/base-project/base-vue/packages/ao-design/src/_styles/theme/_font.scss create mode 100644 code/base-project/base-vue/packages/ao-design/src/_styles/theme/_light.scss create mode 100644 code/base-project/base-vue/packages/ao-design/src/_styles/theme/_radius.scss create mode 100644 code/base-project/base-vue/packages/ao-design/src/_styles/theme/_size.scss create mode 100644 code/base-project/base-vue/packages/ao-design/src/group/index.scss create mode 100644 code/base-project/base-vue/packages/ao-design/src/group/index.tsx diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/_variables.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/_variables.scss new file mode 100644 index 00000000..e626b400 --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/_variables.scss @@ -0,0 +1,126 @@ +// 公共前缀 +// $prefix: 'ao' !default; + +$brand-color-1: var(--td-brand-color-1); +$brand-color-2: var(--td-brand-color-2); +$brand-color-3: var(--td-brand-color-3); +$brand-color-4: var(--td-brand-color-4); +$brand-color-5: var(--td-brand-color-5); +$brand-color-6: var(--td-brand-color-6); +$brand-color-7: var(--td-brand-color-7); +$brand-color-8: var(--td-brand-color-8); +$brand-color-9: var(--td-brand-color-9); +$brand-color-10: var(--td-brand-color-10); + +$warning-color-1: var(--td-warning-color-1); +$warning-color-2: var(--td-warning-color-2); +$warning-color-3: var(--td-warning-color-3); +$warning-color-4: var(--td-warning-color-4); +$warning-color-5: var(--td-warning-color-5); +$warning-color-6: var(--td-warning-color-6); +$warning-color-7: var(--td-warning-color-7); +$warning-color-8: var(--td-warning-color-8); +$warning-color-9: var(--td-warning-color-9); +$warning-color-10: var(--td-warning-color-10); + +$danger-color-1: var(--td-danger-color-1); +$danger-color-2: var(--td-danger-color-2); +$danger-color-3: var(--td-danger-color-3); +$danger-color-4: var(--td-danger-color-4); +$danger-color-5: var(--td-danger-color-5); +$danger-color-6: var(--td-danger-color-6); +$danger-color-7: var(--td-danger-color-7); +$danger-color-8: var(--td-danger-color-8); +$danger-color-9: var(--td-danger-color-9); +$danger-color-10: var(--td-danger-color-10); + +$success-color-1: var(--td-success-color-1); +$success-color-2: var(--td-success-color-2); +$success-color-3: var(--td-success-color-3); +$success-color-4: var(--td-success-color-4); +$success-color-5: var(--td-success-color-5); +$success-color-6: var(--td-success-color-6); +$success-color-7: var(--td-success-color-7); +$success-color-8: var(--td-success-color-8); +$success-color-9: var(--td-success-color-9); +$success-color-10: var(--td-success-color-10); + +$gray-color-1: var(--td-gray-color-1); +$gray-color-2: var(--td-gray-color-2); +$gray-color-3: var(--td-gray-color-3); +$gray-color-4: var(--td-gray-color-4); +$gray-color-5: var(--td-gray-color-5); +$gray-color-6: var(--td-gray-color-6); +$gray-color-7: var(--td-gray-color-7); +$gray-color-8: var(--td-gray-color-8); +$gray-color-9: var(--td-gray-color-9); +$gray-color-10: var(--td-gray-color-10); +$gray-color-11: var(--td-gray-color-11); +$gray-color-12: var(--td-gray-color-12); +$gray-color-13: var(--td-gray-color-13); +$gray-color-14: var(--td-gray-color-14); + +// 文字 & 图标 颜色 +$font-white-1: var(--td-font-white-1); +$font-white-2: var(--td-font-white-2); +$font-white-3: var(--td-font-white-3); +$font-white-4: var(--td-font-white-4); + +$font-gray-1: var(--td-font-gray-1); +$font-gray-2: var(--td-font-gray-2); +$font-gray-3: var(--td-font-gray-3); +$font-gray-4: var(--td-font-gray-4); + +// 基础颜色 +$brand-color: var(--td-brand-color); // 色彩-品牌-可操作 +$warning-color: var(--td-warning-color); // 色彩-功能-警告 +$danger-color: var(--td-danger-color); // 色彩-功能-失败 +$success-color: var(--td-success-color); // 色彩-功能-成功 + +// 基础颜色的扩展 用于 hover / 聚焦 / 禁用 / 点击 等状态 +$brand-color-hover: var(--td-brand-color-hover); // hover态 +$brand-color-focus: var(--td-brand-color-focus); // focus态,包括鼠标和键盘 +$brand-color-active: var(--td-brand-color-active); // 点击态 +$brand-color-disabled: var(--td-brand-color-disabled); // 禁用态 +$brand-color-light: var(--td-brand-color-light); // 浅色的选中态 +$brand-color-light-hover: var(--td-brand-color-light-hover); + +// 警告色扩展 +$warning-color-hover: var(--td-warning-color-hover); +$warning-color-focus: var(--td-warning-color-focus); +$warning-color-active: var(--td-warning-color-active); +$warning-color-disabled: var(--td-warning-color-disabled); +$warning-color-light: var(--td-warning-color-light); +$warning-color-light-hover: var(--td-warning-color-light-hover); + +// 失败/错误色扩展 +$danger-color-hover: var(--td-danger-color-hover); +$danger-color-focus: var(--td-danger-color-focus); +$danger-color-active: var(--td-danger-color-active); +$danger-color-disabled: var(--td-danger-color-disabled); +$danger-color-light: var(--td-danger-color-light); +$danger-color-light-hover: var(--td-danger-color-light-hover); + +// 成功色扩展 +$success-color-hover: var(--td-success-color-hover); +$success-color-focus: var(--td-success-color-focus); +$success-color-active: var(--td-success-color-active); +$success-color-disabled: var(--td-success-color-disabled); +$success-color-light: var(--td-success-color-light); +$success-color-light-hover: var(--td-success-color-light-hover); + +$bg-color-component: var(--td-bg-color-component); // 色彩 - 组件 +$bg-color-component-hover: var(--td-bg-color-component-hover); // 色彩 - 组件 - hover +$bg-color-component-active: var(--td-bg-color-component-active); // 色彩 - 组件 - active +$bg-color-component-disabled: var(--td-bg-color-component-disabled); // 色彩 - 组件 - disabled + +// 文本颜色 +$text-color-primary: var(--td-text-color-primary); // 色彩-文字-主要 +$text-color-secondary: var(--td-text-color-secondary); // 色彩-文字-次要 +$text-color-placeholder: var(--td-text-color-placeholder); // 色彩-文字-占位符/说明 +$text-color-disabled: var(--td-text-color-disabled); // 色彩-文字-禁用 +$text-color-anti: var(--td-text-color-anti); // 色彩-文字-反色 +$text-color-brand: var(--td-text-color-brand); // 色彩-文字-品牌 +$text-color-link: var(--td-text-color-link); // 色彩-文字-链接 + +$border-radius: 2px; diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/index.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/index.scss new file mode 100644 index 00000000..8c893237 --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/index.scss @@ -0,0 +1,3 @@ +@use './variables' as *; + +@use './theme/index.scss' as *; diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_dark.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_dark.scss new file mode 100644 index 00000000..5e8aeaa6 --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_dark.scss @@ -0,0 +1,169 @@ +:root[theme-mode='dark'] { + --td-brand-color-1: #1b2f51; + --td-brand-color-2: #173463; + --td-brand-color-3: #143975; + --td-brand-color-4: #103d88; + --td-brand-color-5: #0d429a; + --td-brand-color-6: #054bbe; + --td-brand-color-7: #2667d4; + --td-brand-color-8: #4582e6; + --td-brand-color-9: #699ef5; + --td-brand-color-10: #96bbf8; + --td-warning-color-1: #4f2a1d; + --td-warning-color-2: #582f21; + --td-warning-color-3: #733c23; + --td-warning-color-4: #a75d2b; + --td-warning-color-5: #cf6e2d; + --td-warning-color-6: #dc7633; + --td-warning-color-7: #e8935c; + --td-warning-color-8: #ecbf91; + --td-warning-color-9: #eed7bf; + --td-warning-color-10: #f3e9dc; + --td-danger-color-1: #472324; + --td-danger-color-2: #5e2a2d; + --td-danger-color-3: #703439; + --td-danger-color-4: #83383e; + --td-danger-color-5: #a03f46; + --td-danger-color-6: #c64751; + --td-danger-color-7: #de6670; + --td-danger-color-8: #ec888e; + --td-danger-color-9: #edb1b6; + --td-danger-color-10: #eeced0; + --td-success-color-1: #193a2a; + --td-success-color-2: #1a4230; + --td-success-color-3: #17533d; + --td-success-color-4: #0d7a55; + --td-success-color-5: #059465; + --td-success-color-6: #43af8a; + --td-success-color-7: #46bf96; + --td-success-color-8: #80d2b6; + --td-success-color-9: #b4e1d3; + --td-success-color-10: #deede8; + --td-gray-color-1: #f3f3f3; + --td-gray-color-2: #eee; + --td-gray-color-3: #e8e8e8; + --td-gray-color-4: #ddd; + --td-gray-color-5: #c6c6c6; + --td-gray-color-6: #a6a6a6; + --td-gray-color-7: #8b8b8b; + --td-gray-color-8: #777; + --td-gray-color-9: #5e5e5e; + --td-gray-color-10: #4b4b4b; + --td-gray-color-11: #393939; + --td-gray-color-12: #2c2c2c; + --td-gray-color-13: #242424; + --td-gray-color-14: #181818; + + // 文字 & 图标 颜色 + --td-font-white-1: rgba(255, 255, 255, 90%); + --td-font-white-2: rgba(255, 255, 255, 55%); + --td-font-white-3: rgba(255, 255, 255, 35%); + --td-font-white-4: rgba(255, 255, 255, 22%); + --td-font-gray-1: rgba(0, 0, 0, 90%); + --td-font-gray-2: rgba(0, 0, 0, 60%); + --td-font-gray-3: rgba(0, 0, 0, 40%); + --td-font-gray-4: rgba(0, 0, 0, 26%); + + // 基础颜色 + --td-brand-color: var(--td-brand-color-8); // 色彩-品牌-可操作 + --td-warning-color: var(--td-warning-color-5); // 色彩-功能-警告 + --td-danger-color: var(--td-danger-color-6); // 色彩-功能-失败 + --td-success-color: var(--td-success-color-5); // 色彩-功能-成功 + + // 基础颜色的扩展 用于 hover / 聚焦 / 禁用 / 点击 等状态 + --td-brand-color-hover: var(--td-brand-color-7); // hover态 + --td-brand-color-focus: var(--td-brand-color-2); // focus态,包括鼠标和键盘 + --td-brand-color-active: var(--td-brand-color-9); // 点击态 + --td-brand-color-disabled: var(--td-brand-color-3); // 禁用态 + --td-brand-color-light: var(--td-brand-color-1); // 浅色的选中态 + --td-brand-color-light-hover: var(--td-brand-color-2); + + // 警告色扩展 + --td-warning-color-hover: var(--td-warning-color-4); + --td-warning-color-focus: var(--td-warning-color-2); + --td-warning-color-active: var(--td-warning-color-6); + --td-warning-color-disabled: var(--td-warning-color-3); + --td-warning-color-light: var(--td-warning-color-1); + --td-warning-color-light-hover: var(--td-warning-color-2); + + // 失败/错误色扩展 + --td-danger-color-hover: var(--td-danger-color-5); + --td-danger-color-focus: var(--td-danger-color-2); + --td-danger-color-active: var(--td-danger-color-7); + --td-danger-color-disabled: var(--td-danger-color-3); + --td-danger-color-light: var(--td-danger-color-1); + --td-danger-color-light-hover: var(--td-danger-color-2); + + // 成功色扩展 + --td-success-color-hover: var(--td-success-color-4); + --td-success-color-focus: var(--td-success-color-2); + --td-success-color-active: var(--td-success-color-6); + --td-success-color-disabled: var(--td-success-color-3); + --td-success-color-light: var(--td-success-color-1); + --td-success-color-light-hover: var(--td-success-color-2); + + // 遮罩 + --td-mask-active: rgba(0, 0, 0, 40%); // 遮罩-弹出 + --td-mask-disabled: rgba(0, 0, 0, 60%); // 遮罩-禁用 + --td-mask-background: rgba(36, 36, 36, 96%); // 二维码遮罩 + + // 背景色 + --td-bg-color-page: var(--td-gray-color-14); // 色彩 - page + --td-bg-color-container: var(--td-gray-color-13); // 色彩 - 容器 + --td-bg-color-container-hover: var(--td-gray-color-12); // 色彩 - 容器 - hover + --td-bg-color-container-active: var(--td-gray-color-10); // 色彩 - 容器 - active + --td-bg-color-container-select: var(--td-gray-color-9); // 色彩 - 容器 - select + --td-bg-color-secondarycontainer: var(--td-gray-color-12); // 色彩 - 次级容器 + --td-bg-color-secondarycontainer-hover: var(--td-gray-color-11); // 色彩 - 次级容器 - hover + --td-bg-color-secondarycontainer-active: var(--td-gray-color-9); // 色彩 - 次级容器 - active + --td-bg-color-component: var(--td-gray-color-11); // 色彩 - 组件 + --td-bg-color-component-hover: var(--td-gray-color-10); // 色彩 - 组件 - hover + --td-bg-color-component-active: var(--td-gray-color-9); // 色彩 - 组件 - active + --td-bg-color-secondarycomponent: var(--td-gray-color-10); // 色彩 - 次级组件 + --td-bg-color-secondarycomponent-hover: var(--td-gray-color-9); // 色彩 - 次级组件 - hover + --td-bg-color-secondarycomponent-active: var(--td-gray-color-8); // 色彩 - 次级组件 - active + --td-bg-color-component-disabled: var(--td-gray-color-12); // 色彩 - 组件 - disabled + + // 特殊组件背景色,目前只用于 button、input 组件多主题场景,浅色主题下固定为白色,深色主题下为 transparent 适配背景颜色 + --td-bg-color-specialcomponent: transparent; + + // 文本颜色 + --td-text-color-primary: var(--td-font-white-1); // 色彩-文字-主要 + --td-text-color-secondary: var(--td-font-white-2); // 色彩-文字-次要 + --td-text-color-placeholder: var(--td-font-white-3); // 色彩-文字-占位符/说明 + --td-text-color-disabled: var(--td-font-white-4); // 色彩-文字-禁用 + --td-text-color-anti: #fff; // 色彩-文字-反色 + --td-text-color-brand: var(--td-brand-color-8); // 色彩-文字-品牌 + --td-text-color-link: var(--td-brand-color-8); // 色彩-文字-链接 + --td-text-color-watermark: rgba(255, 255, 255, 10%); // 色彩-文字-水印颜色 + + // 分割线 + --td-border-level-1-color: var(--td-gray-color-11); + --td-component-stroke: var(--td-gray-color-11); + // 边框 + --td-border-level-2-color: var(--td-gray-color-9); + --td-component-border: var(--td-gray-color-9); + + // 基础/下层 投影 hover 使用的组件包括:表格 / + --td-shadow-1: 0 4px 6px rgba(0, 0, 0, 6%), 0 1px 10px rgba(0, 0, 0, 8%), 0 2px 4px rgba(0, 0, 0, 12%); + // 中层投影 下拉 使用的组件包括:下拉菜单 / 气泡确认框 / 选择器 / + --td-shadow-2: 0 8px 10px rgba(0, 0, 0, 12%), 0 3px 14px rgba(0, 0, 0, 10%), 0 5px 5px rgba(0, 0, 0, 16%); + // 上层投影(警示/弹窗)使用的组件包括:全局提示 / 消息通知 + --td-shadow-3: 0 16px 24px rgba(0, 0, 0, 14%), 0 6px 30px rgba(0, 0, 0, 12%), 0 8px 10px rgba(0, 0, 0, 20%); + // 内投影 用于弹窗类组件(气泡确认框 / 全局提示 / 消息通知)的内描边 + + --td-shadow-inset-top: inset 0 0.5px 0 #5e5e5e; + --td-shadow-inset-right: inset 0.5px 0 0 #5e5e5e; + --td-shadow-inset-bottom: inset 0 -0.5px 0 #5e5e5e; + --td-shadow-inset-left: inset -0.5px 0 0 #5e5e5e; + + // table 特定阴影 + --td-table-shadow-color: rgba(0, 0, 0, 55%); + + // 滚动条颜色 + --td-scrollbar-color: rgba(255, 255, 255, 10%); + // 滚动条悬浮颜色( hover ) + --td-scrollbar-hover-color: rgba(255, 255, 255, 30%); + // 滚动条轨道颜色,不能是带透明度,否则纵向滚动时,横向滚动条会穿透 + --td-scroll-track-color: #333; +} diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_font.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_font.scss new file mode 100644 index 00000000..df20508f --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_font.scss @@ -0,0 +1,70 @@ +// 字体相关token +:root { + // 字体family token + --td-font-family: PingFang SC, Microsoft YaHei, Arial Regular; + --td-font-family-medium: PingFang SC, Microsoft YaHei, Arial Medium; + + // 字体大小 token + --td-font-size-link-small: 12px; + --td-font-size-link-medium: 14px; + --td-font-size-link-large: 16px; + --td-font-size-mark-small: 12px; + --td-font-size-mark-medium: 14px; + --td-font-size-body-small: 12px; + --td-font-size-body-medium: 13px; + --td-font-size-body-large: 1px; + --td-font-size-title-small: 14px; + --td-font-size-title-medium: 16px; + --td-font-size-title-large: 18px; + --td-font-size-title-extraLarge: 20px; + --td-font-size-headline-small: 24px; + --td-font-size-headline-medium: 28px; + --td-font-size-headline-large: 36px; + --td-font-size-display-medium: 48px; + --td-font-size-display-large: 64px; + + // 字体行高 token + --td-line-height-link-small: 20px; + --td-line-height-link-medium: 22px; + --td-line-height-link-large: 24px; + --td-line-height-mark-small: 20px; + --td-line-height-mark-medium: 22px; + --td-line-height-body-small: 20px; + --td-line-height-body-medium: 22px; + --td-line-height-body-large: 24px; + --td-line-height-title-small: 22px; + --td-line-height-title-medium: 24px; + --td-line-height-title-large: 26px; + --td-line-height-title-extraLarge: 28px; + --td-line-height-headline-small: 32px; + --td-line-height-headline-medium: 36px; + --td-line-height-headline-large: 44px; + --td-line-height-display-medium: 56px; + --td-line-height-display-large: 72px; + + // font token + --td-font-link-small: var(--td-font-size-link-small) / var(--td-line-height-link-small) var(--td-font-family); + --td-font-link-medium: var(--td-font-size-link-medium) / var(--td-line-height-link-medium) var(--td-font-family); + --td-font-link-large: var(--td-font-size-link-large) / var(--td-line-height-link-large) var(--td-font-family); + --td-font-mark-small: 600 var(--td-font-size-mark-small) / var(--td-line-height-mark-small) var(--td-font-family); + --td-font-mark-medium: 600 var(--td-font-size-mark-medium) / var(--td-line-height-mark-medium) var(--td-font-family); + --td-font-body-small: var(--td-font-size-body-small) / var(--td-line-height-body-small) var(--td-font-family); + --td-font-body-medium: var(--td-font-size-body-medium) / var(--td-line-height-body-medium) var(--td-font-family); + --td-font-body-large: var(--td-font-size-body-large) / var(--td-line-height-body-large) var(--td-font-family); + --td-font-title-small: 600 var(--td-font-size-title-small) / var(--td-line-height-title-small) var(--td-font-family); + --td-font-title-medium: 600 var(--td-font-size-title-medium) / var(--td-line-height-title-medium) + var(--td-font-family); + --td-font-title-large: 600 var(--td-font-size-title-large) / var(--td-line-height-title-large) var(--td-font-family); + --td-font-title-extraLarge: 600 var(--td-font-size-title-extraLarge) / var(--td-line-height-title-extraLarge) + var(--td-font-family); + --td-font-headline-small: 600 var(--td-font-size-headline-small) / var(--td-line-height-headline-small) + var(--td-font-family); + --td-font-headline-medium: 600 var(--td-font-size-headline-medium) / var(--td-line-height-headline-medium) + var(--td-font-family); + --td-font-headline-large: 600 var(--td-font-size-headline-large) / var(--td-line-height-headline-large) + var(--td-font-family); + --td-font-display-medium: 600 var(--td-font-size-display-medium) / var(--td-line-height-display-medium) + var(--td-font-family); + --td-font-display-large: 600 var(--td-font-size-display-large) / var(--td-line-height-display-large) + var(--td-font-family); +} diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_light.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_light.scss new file mode 100644 index 00000000..45d00bd7 --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_light.scss @@ -0,0 +1,170 @@ +:root, +:root[theme-mode='light'] { + --td-brand-color-1: #f2f3ff; + --td-brand-color-2: #d9e1ff; + --td-brand-color-3: #b5c7ff; + --td-brand-color-4: #8eabff; + --td-brand-color-5: #618dff; + --td-brand-color-6: #366ef4; + --td-brand-color-7: #0052d9; + --td-brand-color-8: #003cab; + --td-brand-color-9: #002a7c; + --td-brand-color-10: #001a57; + --td-warning-color-1: #fff1e9; + --td-warning-color-2: #ffd9c2; + --td-warning-color-3: #ffb98c; + --td-warning-color-4: #fa9550; + --td-warning-color-5: #e37318; + --td-warning-color-6: #be5a00; + --td-warning-color-7: #954500; + --td-warning-color-8: #713300; + --td-warning-color-9: #532300; + --td-warning-color-10: #3b1700; + --td-danger-color-1: #fff0ed; + --td-danger-color-2: #ffd8d2; + --td-danger-color-3: #ffb9b0; + --td-danger-color-4: #ff9285; + --td-danger-color-5: #f6685d; + --td-danger-color-6: #d54941; + --td-danger-color-7: #ad352f; + --td-danger-color-8: #881f1c; + --td-danger-color-9: #68070a; + --td-danger-color-10: #490002; + --td-success-color-1: #e3f9e9; + --td-success-color-2: #c6f3d7; + --td-success-color-3: #92dab2; + --td-success-color-4: #56c08d; + --td-success-color-5: #2ba471; + --td-success-color-6: #008858; + --td-success-color-7: #006c45; + --td-success-color-8: #005334; + --td-success-color-9: #003b23; + --td-success-color-10: #002515; + --td-gray-color-1: #f3f3f3; + --td-gray-color-2: #eee; + --td-gray-color-3: #e8e8e8; + --td-gray-color-4: #ddd; + --td-gray-color-5: #c6c6c6; + --td-gray-color-6: #a6a6a6; + --td-gray-color-7: #8b8b8b; + --td-gray-color-8: #777; + --td-gray-color-9: #5e5e5e; + --td-gray-color-10: #4b4b4b; + --td-gray-color-11: #393939; + --td-gray-color-12: #2c2c2c; + --td-gray-color-13: #242424; + --td-gray-color-14: #181818; + + // 文字 & 图标 颜色 + --td-font-white-1: rgba(255, 255, 255, 100%); + --td-font-white-2: rgba(255, 255, 255, 55%); + --td-font-white-3: rgba(255, 255, 255, 35%); + --td-font-white-4: rgba(255, 255, 255, 22%); + --td-font-gray-1: rgba(0, 0, 0, 90%); + --td-font-gray-2: rgba(0, 0, 0, 60%); + --td-font-gray-3: rgba(0, 0, 0, 40%); + --td-font-gray-4: rgba(0, 0, 0, 26%); + + // 基础颜色 + --td-brand-color: var(--td-brand-color-7); // 色彩-品牌-可操作 + --td-warning-color: var(--td-warning-color-5); // 色彩-功能-警告 + --td-danger-color: var(--td-danger-color-6); // 色彩-功能-失败 + --td-success-color: var(--td-success-color-5); // 色彩-功能-成功 + + // 基础颜色的扩展 用于 hover / 聚焦 / 禁用 / 点击 等状态 + --td-brand-color-hover: var(--td-brand-color-6); // hover态 + --td-brand-color-focus: var(--td-brand-color-2); // focus态,包括鼠标和键盘 + --td-brand-color-active: var(--td-brand-color-8); // 点击态 + --td-brand-color-disabled: var(--td-brand-color-3); // 禁用态 + --td-brand-color-light: var(--td-brand-color-1); // 浅色的选中态 + --td-brand-color-light-hover: var(--td-brand-color-2); + + // 警告色扩展 + --td-warning-color-hover: var(--td-warning-color-4); + --td-warning-color-focus: var(--td-warning-color-2); + --td-warning-color-active: var(--td-warning-color-6); + --td-warning-color-disabled: var(--td-warning-color-3); + --td-warning-color-light: var(--td-warning-color-1); + --td-warning-color-light-hover: var(--td-warning-color-2); + + // 失败/错误色扩展 + --td-danger-color-hover: var(--td-danger-color-5); + --td-danger-color-focus: var(--td-danger-color-2); + --td-danger-color-active: var(--td-danger-color-7); + --td-danger-color-disabled: var(--td-danger-color-3); + --td-danger-color-light: var(--td-danger-color-1); + --td-danger-color-light-hover: var(--td-danger-color-2); + + // 成功色扩展 + --td-success-color-hover: var(--td-success-color-4); + --td-success-color-focus: var(--td-success-color-2); + --td-success-color-active: var(--td-success-color-6); + --td-success-color-disabled: var(--td-success-color-3); + --td-success-color-light: var(--td-success-color-1); + --td-success-color-light-hover: var(--td-success-color-2); + + // 遮罩 + --td-mask-active: rgba(0, 0, 0, 60%); // 遮罩-弹出 + --td-mask-disabled: rgba(255, 255, 255, 60%); // 遮罩-禁用 + --td-mask-background: rgba(255, 255, 255, 96%); // 二维码遮罩 + + // 背景色 + --td-bg-color-page: var(--td-gray-color-2); // 色彩 - page + --td-bg-color-container: #fff; // 色彩 - 容器 + --td-bg-color-container-hover: var(--td-gray-color-1); // 色彩 - 容器 - hover + --td-bg-color-container-active: var(--td-gray-color-3); // 色彩 - 容器 - active + --td-bg-color-container-select: #fff; // 色彩 - 容器 - select + --td-bg-color-secondarycontainer: var(--td-gray-color-1); // 色彩 - 次级容器 + --td-bg-color-secondarycontainer-hover: var(--td-gray-color-2); // 色彩 - 次级容器 - hover + --td-bg-color-secondarycontainer-active: var(--td-gray-color-4); // 色彩 - 次级容器 - active + --td-bg-color-component: var(--td-gray-color-3); // 色彩 - 组件 + --td-bg-color-component-hover: var(--td-gray-color-4); // 色彩 - 组件 - hover + --td-bg-color-component-active: var(--td-gray-color-6); // 色彩 - 组件 - active + --td-bg-color-secondarycomponent: var(--td-gray-color-4); // 色彩 - 次级组件 + --td-bg-color-secondarycomponent-hover: var(--td-gray-color-5); // 色彩 - 次级组件 - hover + --td-bg-color-secondarycomponent-active: var(--td-gray-color-6); // 色彩 - 次级组件 - active + --td-bg-color-component-disabled: var(--td-gray-color-2); // 色彩 - 组件 - disabled + + // 特殊组件背景色,目前只用于 button、input 组件多主题场景,浅色主题下固定为白色,深色主题下为 transparent 适配背景颜色 + --td-bg-color-specialcomponent: #fff; + + // 文本颜色 + --td-text-color-primary: var(--td-font-gray-1); // 色彩-文字-主要 + --td-text-color-secondary: var(--td-font-gray-2); // 色彩-文字-次要 + --td-text-color-placeholder: var(--td-font-gray-3); // 色彩-文字-占位符/说明 + --td-text-color-disabled: var(--td-font-gray-4); // 色彩-文字-禁用 + --td-text-color-anti: #fff; // 色彩-文字-反色 + --td-text-color-brand: var(--td-brand-color-7); // 色彩-文字-品牌 + --td-text-color-link: var(--td-brand-color-8); // 色彩-文字-链接 + --td-text-color-watermark: rgba(0, 0, 0, 10%); // 色彩-文字-水印颜色 + + // 分割线 + --td-border-level-1-color: var(--td-gray-color-3); + --td-component-stroke: var(--td-gray-color-3); + // 边框 + --td-border-level-2-color: var(--td-gray-color-4); + --td-component-border: var(--td-gray-color-4); + + // 基础/下层 投影 hover 使用的组件包括:表格 / + --td-shadow-1: 0 1px 10px rgba(0, 0, 0, 5%), 0 4px 5px rgba(0, 0, 0, 8%), 0 2px 4px -1px rgba(0, 0, 0, 12%); + // 中层投影 下拉 使用的组件包括:下拉菜单 / 气泡确认框 / 选择器 / + --td-shadow-2: 0 3px 14px 2px rgba(0, 0, 0, 5%), 0 8px 10px 1px rgba(0, 0, 0, 6%), 0 5px 5px -3px rgba(0, 0, 0, 10%); + // 上层投影(警示/弹窗)使用的组件包括:全局提示 / 消息通知 + --td-shadow-3: 0 6px 30px 5px rgba(0, 0, 0, 5%), 0 16px 24px 2px rgba(0, 0, 0, 4%), 0 8px 10px -5px rgba(0, 0, 0, 8%); + + // 内投影 用于弹窗类组件(气泡确认框 / 全局提示 / 消息通知)的内描边 + --td-shadow-inset-top: inset 0 0.5px 0 #dcdcdc; + --td-shadow-inset-right: inset 0.5px 0 0 #dcdcdc; + --td-shadow-inset-bottom: inset 0 -0.5px 0 #dcdcdc; + --td-shadow-inset-left: inset -0.5px 0 0 #dcdcdc; + + // table 特定阴影 + --td-table-shadow-color: rgba(0, 0, 0, 8%); + + // 滚动条颜色 + --td-scrollbar-color: rgba(0, 0, 0, 10%); + // 滚动条悬浮颜色( hover ) + --td-scrollbar-hover-color: rgba(0, 0, 0, 30%); + // 滚动条轨道颜色,不能是带透明度,否则纵向滚动时,横向滚动条会穿透 + --td-scroll-track-color: #fff; +} diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_radius.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_radius.scss new file mode 100644 index 00000000..ae55f19f --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_radius.scss @@ -0,0 +1,10 @@ +// border-radius相关 token +:root { + --td-radius-small: 2px; + --td-radius-default: 3px; + --td-radius-medium: 6px; + --td-radius-large: 9px; + --td-radius-extraLarge: 12px; + --td-radius-round: 999px; + --td-radius-circle: 50%; +} diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_size.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_size.scss new file mode 100644 index 00000000..0246566c --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/_size.scss @@ -0,0 +1,19 @@ +// size/margin/padding相关 token +:root { + --td-size-2: 2px; + --td-size-4: 4px; + --td-size-6: 6px; + --td-size-8: 8px; + --td-size-12: 12px; + --td-size-16: 16px; + --td-size-20: 20px; + --td-size-24: 24px; + --td-size-28: 28px; + --td-size-32: 32px; + --td-size-36: 36px; + --td-size-40: 40px; + --td-size-48: 48px; + --td-size-56: 56px; + --td-size-64: 64px; + --td-size-72: 72px; +} diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/index.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/index.scss index 321f235d..72096001 100644 --- a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/index.scss @@ -1,11 +1,34 @@ +@use './_light' as *; +@use './_dark' as *; +@use './_radius' as *; +@use './_font' as *; +@use './_size' as *; + $prefix: 'ao' !default; -$default-color: #0064fa !default; +$default-color: #165dff !default; $primary-color: $default-color !default; -$danger-color: #f93920 !default; -$warning-color: #fc8800 !default; -$success-color: #22c55e !default; +// $danger-color: #f53f3f !default; +// $warning-color: #ff7d00 !default; +// $success-color: #00b42a !default; +// $border-radius: 2px; -$input-hover-color: $default-color; -$input-focus-color: $default-color; -$input-focus-shadow: 0 0 0 2px #edf4ff; +$input-border-color: #ddd; +$input-border: 1px solid $input-border-color; + +$input-hover-border-color: $primary-color; +$input-focus-border-color: $primary-color; + +$input-hover-border: 1px solid $input-hover-border-color; +$input-focus-border: 1px solid $input-focus-border-color; + +$input-focus-shadow: 0 0 0 2px rgba($primary-color, 0.2); + +$input-placeholder-color: #999999; +$input-icon-wrapper-size: 18px; +$input-affix-color: #6e6e6e; +$input-icon-hover-bg-color: #f2f3f5; + +$input-readonly-bg-color: #fdfdfd; +$input-disabled-bg-color: #fafafc; +$input-disabled-font-color: #a8a8a8; diff --git a/code/base-project/base-vue/packages/ao-design/src/button/index.scss b/code/base-project/base-vue/packages/ao-design/src/button/index.scss index 8622146b..644813f1 100644 --- a/code/base-project/base-vue/packages/ao-design/src/button/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/button/index.scss @@ -1,17 +1,9 @@ @use 'sass:color'; +@use '../_styles/variables' as *; + @use '../_styles/theme/index' as *; $btn-prefix: #{$prefix}-btn; -$btn-hover-bgcolor: #f4f5f5; -$btn-active-bgcolor: #eceded; - -@function color-hover($color, $amount: 8%) { - @return color.scale($color, $lightness: -$amount); -} - -@function color-active($color, $amount: 12%) { - @return color.scale($color, $lightness: -$amount); -} .#{$btn-prefix} { display: inline-flex; @@ -22,7 +14,7 @@ $btn-active-bgcolor: #eceded; vertical-align: middle; user-select: none; vertical-align: middle; - border-radius: 2px; + border-radius: $border-radius; cursor: pointer; transition: all 0.2s ease; font-weight: 500; @@ -73,121 +65,58 @@ $btn-active-bgcolor: #eceded; opacity: 0.6; } - /* ===== Solid 按钮 ===== */ &-solid { - @each $status, - $color - in ( - normal: #d9d9d9, - primary: $primary-color, - danger: $danger-color, - warning: $warning-color, - success: $success-color - ) - { - &.#{$btn-prefix}-status-#{$status} { - @if $status == normal { - background: #f4f5f5; - color: #000; - &:hover:enabled { - background: #eceded; - } - &:active:enabled { - background: #e4e4e5; - } - } @else { - background: $color; - color: #fff; - border: 1px solid transparent; - &:hover:enabled { - background: color-hover($color, 5%); - } - &:active:enabled { - background: color-active($color, -5%); - } - } + &.#{$btn-prefix}-status-normal { + background: $bg-color-component; + color: $text-color-primary; + &:hover:enabled { + background: $bg-color-component-hover; + } + &:active:enabled { + background: $bg-color-component-active; } } - } - /* ===== Outline 按钮 ===== */ - &-outline { - background: transparent; - - @each $status, - $color - in ( - normal: $primary-color, - primary: $primary-color, - danger: $danger-color, - warning: $warning-color, - success: $success-color - ) - { - &.#{$btn-prefix}-status-#{$status} { - color: if($status == normal, #000, $color); - border-color: if($status == normal, #d9d9d9, $color); - &:hover:enabled { - background-color: $btn-hover-bgcolor; - } - &:active:enabled { - background-color: $btn-active-bgcolor; - } + &.#{$btn-prefix}-status-primary { + background: $brand-color; + color: $text-color-anti; + &:hover:enabled { + background: $brand-color-hover; + } + &:active:enabled { + background: $brand-color-active; } } - } - /* ===== Dashed 按钮 ===== */ - &-dashed { - background: transparent; - border: 1px dashed currentColor; - - @each $status, - $color - in ( - normal: #000, - primary: $primary-color, - danger: $danger-color, - warning: $warning-color, - success: $success-color - ) - { - &.#{$btn-prefix}-status-#{$status} { - color: $color; - border-color: if($status == normal, #d9d9d9, $color); - &:hover:enabled { - background-color: $btn-hover-bgcolor; - } - &:active:enabled { - background-color: $btn-active-bgcolor; - } + &.#{$btn-prefix}-status-danger { + background: $danger-color; + color: $text-color-anti; + &:hover:enabled { + background: $danger-color-hover; + } + &:active:enabled { + background: $danger-color-active; } } - } - /* ===== Text 按钮 ===== */ - &-text { - background: transparent; - border: none; - - @each $status, - $color - in ( - normal: #000, - primary: $primary-color, - danger: $danger-color, - warning: $warning-color, - success: $success-color - ) - { - &.#{$btn-prefix}-status-#{$status} { - color: $color; - &:hover:enabled { - background-color: $btn-hover-bgcolor; - } - &:active:enabled { - background-color: $btn-active-bgcolor; - } + &.#{$btn-prefix}-status-warning { + background: $warning-color; + color: $text-color-anti; + &:hover:enabled { + background: $warning-color-hover; + } + &:active:enabled { + background: $warning-color-active; + } + } + &.#{$btn-prefix}-status-success { + background: $success-color; + color: $text-color-anti; + &:hover:enabled { + background: $success-color-hover; + } + &:active:enabled { + background: $success-color-active; } } } diff --git a/code/base-project/base-vue/packages/ao-design/src/components.ts b/code/base-project/base-vue/packages/ao-design/src/components.ts index a798e396..0972f3c1 100644 --- a/code/base-project/base-vue/packages/ao-design/src/components.ts +++ b/code/base-project/base-vue/packages/ao-design/src/components.ts @@ -1,5 +1,6 @@ export { default as ConfigProvider } from './_config' export { default as Button } from './button' +export { default as Group } from './group' export { default as Icon } from './icon' export { default as Input } from './input' export { default as Spin } from './spin' diff --git a/code/base-project/base-vue/packages/ao-design/src/group/index.scss b/code/base-project/base-vue/packages/ao-design/src/group/index.scss new file mode 100644 index 00000000..0b9cd7ce --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/group/index.scss @@ -0,0 +1,44 @@ +@use '../_styles/theme/index' as *; +@use 'sass:color'; + +$group-prefix: #{$prefix}-group; + +.#{$group-prefix}-wrapper { + display: flex; + width: 100%; + border-radius: $border-radius; + overflow: hidden; + + > * { + flex: 1; + margin: 0; + border-radius: 0; + position: relative; + + border: $input-border; + border-left: none; + box-shadow: none; + &:hover { + border-left: $input-hover-border; + z-index: 1; + box-shadow: none; + } + &:focus-within, + &:active { + border-left: $input-focus-border; + z-index: 1; + box-shadow: none; + } + } + + > *:first-child { + border-left: $input-border; + border-top-left-radius: $border-radius; + border-bottom-left-radius: $border-radius; + } + + > *:last-child { + border-top-right-radius: $border-radius; + border-bottom-right-radius: $border-radius; + } +} diff --git a/code/base-project/base-vue/packages/ao-design/src/group/index.tsx b/code/base-project/base-vue/packages/ao-design/src/group/index.tsx new file mode 100644 index 00000000..b979fd57 --- /dev/null +++ b/code/base-project/base-vue/packages/ao-design/src/group/index.tsx @@ -0,0 +1,17 @@ +import type { PropType } from 'vue' +import { defineComponent } from 'vue' +import { getPrefixCls } from '../_utils/getPrefixCls' + +export default defineComponent({ + name: 'Group', + props: {}, + setup(props, { slots }) { + const prefixCls = getPrefixCls('group') + + return () => ( +
+ {slots.default?.()} +
+ ) + }, +}) diff --git a/code/base-project/base-vue/packages/ao-design/src/icon/index.scss b/code/base-project/base-vue/packages/ao-design/src/icon/index.scss index 779060cf..34196ddb 100644 --- a/code/base-project/base-vue/packages/ao-design/src/icon/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/icon/index.scss @@ -1,8 +1,15 @@ @use '../_styles/theme/index' as *; -.#{$prefix}-icon-spin { - animation: spin 1s linear infinite; - --rotate-angle: 360deg; +$icon-prefix: #{$prefix}-icon; + +.#{$icon-prefix} { + display: inline-flex; + align-items: center; + justify-content: center; + &-spin { + animation: spin 1s linear infinite; + --rotate-angle: 360deg; + } } @keyframes spin { diff --git a/code/base-project/base-vue/packages/ao-design/src/icon/index.tsx b/code/base-project/base-vue/packages/ao-design/src/icon/index.tsx index 13ef76f3..520cd32d 100644 --- a/code/base-project/base-vue/packages/ao-design/src/icon/index.tsx +++ b/code/base-project/base-vue/packages/ao-design/src/icon/index.tsx @@ -11,29 +11,20 @@ export default defineComponent({ size: { type: Number, default: 16 }, color: { type: String, default: 'currentColor' }, spin: { type: Boolean, default: false }, - rotate: { type: Number, default: 360 }, }, setup(props) { const prefixCls = getPrefixCls('icon') return () => ( ) diff --git a/code/base-project/base-vue/packages/ao-design/src/index.scss b/code/base-project/base-vue/packages/ao-design/src/index.scss index 4d3f5cf3..c6f8a736 100644 --- a/code/base-project/base-vue/packages/ao-design/src/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/index.scss @@ -1,6 +1,7 @@ @use './button/index.scss' as *; @use './input/index.scss' as *; @use './textarea/index.scss' as *; +@use './group/index.scss' as *; input, button, diff --git a/code/base-project/base-vue/packages/ao-design/src/input/index.scss b/code/base-project/base-vue/packages/ao-design/src/input/index.scss index b7e272eb..67172535 100644 --- a/code/base-project/base-vue/packages/ao-design/src/input/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/input/index.scss @@ -3,69 +3,20 @@ $input-prefix: #{$prefix}-input; -.#{$input-prefix}-adornment { - display: flex; - width: 100%; - box-sizing: border-box; - margin: 0; - padding: 0; - list-style: none; - - &.#{$input-prefix}-size { - &-small { - height: 24px; - font-size: 12px; - } - - &-medium { - height: 28px; - font-size: 13px; - } - - &-large { - height: 32px; - font-size: 14px; - } +.#{$input-prefix}-size { + &-small { + height: 24px; + font-size: 12px; } - .#{$input-prefix}-adornment-prepend, - .#{$input-prefix}-adornment-append { - display: inline-flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - - background-color: #f3f3f3; - color: rgba(0, 0, 0, 0.9); - border: 1px solid #ddd; - - span { - white-space: nowrap; - word-break: keep-all; - padding: 0 8px; - } + &-medium { + height: 28px; + font-size: 13px; } - .#{$input-prefix}-adornment-prepend { - border-right: none; - } - - .#{$input-prefix}-adornment-append { - border-left: none; - } - - .#{$input-prefix}-wrapper { - border-radius: 0px; - } - - > :first-child { - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; - } - - > :last-child { - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; + &-large { + height: 32px; + font-size: 14px; } } @@ -73,9 +24,9 @@ $input-prefix: #{$prefix}-input; display: flex; align-items: center; width: 100%; - border: 1px solid #ddd; + border: $input-border; + border-radius: $border-radius; - z-index: 2; box-sizing: border-box; padding: 0 8px; transition: @@ -83,7 +34,7 @@ $input-prefix: #{$prefix}-input; box-shadow cubic-bezier(0.38, 0, 0.24, 1) 0.2s, background-color cubic-bezier(0.38, 0, 0.24, 1) 0.2s; - .#{$input-prefix}-input { + .#{$input-prefix}-inner { width: 100%; border: none; outline: none; @@ -97,16 +48,16 @@ $input-prefix: #{$prefix}-input; height: 100%; &::placeholder { - color: #999999; + color: $input-placeholder-color; } } &:hover { - border-color: $input-hover-color; + border-color: $input-hover-border-color; } &:focus-within { - border-color: $input-focus-color; + border-color: $input-focus-border-color; box-shadow: $input-focus-shadow; } @@ -139,37 +90,48 @@ $input-prefix: #{$prefix}-input; } &.#{$input-prefix}-disabled { - background-color: #fafafc; + background-color: $input-disabled-bg-color; cursor: not-allowed; .#{$input-prefix}-input { - color: #a8a8a8; + color: $input-disabled-font-color; } .#{$input-prefix}-input::placeholder { - color: #a8a8a8; + color: $input-disabled-font-color; } .#{$input-prefix}-prefix, .#{$input-prefix}-suffix { - color: #a8a8a8; + color: $input-disabled-font-color; } &:hover, &:focus-within { - border-color: #ddd; + border-color: $input-border-color; box-shadow: none; } } &.#{$input-prefix}-readonly { - background-color: #fdfdfd; + background-color: $input-readonly-bg-color; } - .#{$input-prefix}-clear { + .#{$input-prefix}-icon { cursor: pointer; - transition: color 0.2s; + transition: + color 0.2s, + background-color 0.2s; + color: $input-affix-color; + + display: inline-flex; + align-items: center; + justify-content: center; + + width: $input-icon-wrapper-size; + height: $input-icon-wrapper-size; &:hover { - color: red !important; + background-color: $input-icon-hover-bg-color; + border-radius: 50%; } } @@ -177,9 +139,6 @@ $input-prefix: #{$prefix}-input; flex-shrink: 0; margin-left: 4px; white-space: nowrap; - } - - .#{$input-prefix}-password { - cursor: pointer !important; + color: $input-affix-color; } } diff --git a/code/base-project/base-vue/packages/ao-design/src/input/index.tsx b/code/base-project/base-vue/packages/ao-design/src/input/index.tsx index d8e0bda4..d9d7f16d 100644 --- a/code/base-project/base-vue/packages/ao-design/src/input/index.tsx +++ b/code/base-project/base-vue/packages/ao-design/src/input/index.tsx @@ -24,13 +24,12 @@ export default defineComponent({ showCount: Boolean, maxlength: Number, password: Boolean, - prepend: String, - append: String, }, emits: ['update:modelValue'], setup(props, { slots, emit }) { const prefixCls = getPrefixCls('input') const inputValue = ref(props.modelValue || '') + const inputRef = ref(null) // 控制密码显示/隐藏 const showPassword = ref(false) @@ -53,11 +52,20 @@ export default defineComponent({ return showPassword.value ? 'text' : 'password' }) - const inputWrapper = () => { + const clearValue = () => { + updateValue('') + + if (inputRef.value) { + inputRef.value.focus() + } + } + + return () => { return (
updateValue('')} + class={`${prefixCls}-suffix ${prefixCls}-icon`} + onClick={clearValue} > - )} {/* 密码切换图标 */} {props.password && ( (showPassword.value = !showPassword.value)} > - + )} {(slots.suffix || props.suffixIcon) && !props.password && (
- {slots.suffix?.() ?? } + {slots.suffix?.() ?? }
)} @@ -113,29 +120,5 @@ export default defineComponent({
) } - - return () => { - return ( -
- {props.prepend || slots.prepend - ? ( -
- {slots.prepend?.() ?? (props.prepend && {props.prepend})} -
- ) - : null} - - {inputWrapper()} - - {props.append || slots.append - ? ( -
- {slots.append?.() ?? (props.append && {props.append})} -
- ) - : null} -
- ) - } }, }) diff --git a/code/base-project/base-vue/packages/ao-design/src/spin/index.tsx b/code/base-project/base-vue/packages/ao-design/src/spin/index.tsx index 2ee2ac5b..251908f9 100644 --- a/code/base-project/base-vue/packages/ao-design/src/spin/index.tsx +++ b/code/base-project/base-vue/packages/ao-design/src/spin/index.tsx @@ -36,8 +36,7 @@ export default defineComponent({
diff --git a/code/base-project/base-vue/packages/ao-design/src/textarea/index.scss b/code/base-project/base-vue/packages/ao-design/src/textarea/index.scss index 37035dbe..109911f8 100644 --- a/code/base-project/base-vue/packages/ao-design/src/textarea/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/textarea/index.scss @@ -4,35 +4,105 @@ $textarea-prefix: #{$prefix}-textarea; .#{$textarea-prefix}-wrapper { - width: 100%; - border: 1px solid #ddd; - border-radius: 2px; box-sizing: border-box; - position: relative; + margin: 0; padding: 0; - - &:hover { - border-color: $input-hover-color; - } - - &:focus-within { - border-color: $input-focus-color; - box-shadow: $input-focus-shadow; - } + list-style: none; + position: relative; + width: 100%; .#{$textarea-prefix}-inner { width: 100%; - min-height: 80px; // 可根据需要 - padding: 8px; // 内边距 - border: none; // 去掉默认边框 + display: flex; + padding: 5px 8px; + border: none; outline: none; resize: vertical; box-sizing: border-box; font-size: 13px; - color: #000; + transition: + all cubic-bezier(0.38, 0, 0.24, 1) 0.2s, + height 0s; + border: $input-border; + border-radius: $border-radius; &::placeholder { - color: #999999; + color: $input-placeholder-color; + } + + &:hover { + border-color: $input-hover-border-color; + } + + &:focus-within { + border-color: $input-focus-border-color; + box-shadow: $input-focus-shadow; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background: transparent; + } + + &::-webkit-scrollbar-thumb { + background-color: #e5e5e5; + border-radius: 0px; + } + + &::-webkit-scrollbar-thumb:hover { + background-color: #b2b2b2; } } + + .#{$textarea-prefix}-disabled { + background-color: $input-disabled-bg-color; + cursor: not-allowed; + color: $input-disabled-font-color; + + &:hover, + &:focus-within { + border-color: $input-border-color; + box-shadow: none; + } + } + + .#{$textarea-prefix}-readonly { + background-color: $input-readonly-bg-color; + } + + .#{$textarea-prefix}-clear { + position: absolute; + right: 8px; + top: 50%; + transform: translateY(-50%); + cursor: pointer; + + width: $input-icon-wrapper-size; + height: $input-icon-wrapper-size; + + display: flex; + align-items: center; + justify-content: center; + + color: $input-affix-color; + transition: + color 0.2s, + background-color 0.2s; + + &:hover { + background-color: $input-icon-hover-bg-color; + border-radius: 50%; + } + } + + .#{$textarea-prefix}-count { + position: absolute; + right: 8px; + bottom: 0px; + font-size: 12px; + color: $input-affix-color; + } } diff --git a/code/base-project/base-vue/packages/ao-design/src/textarea/index.tsx b/code/base-project/base-vue/packages/ao-design/src/textarea/index.tsx index bc0b7c1a..74357665 100644 --- a/code/base-project/base-vue/packages/ao-design/src/textarea/index.tsx +++ b/code/base-project/base-vue/packages/ao-design/src/textarea/index.tsx @@ -1,17 +1,129 @@ import type { PropType } from 'vue' -import { computed, defineComponent, ref } from 'vue' +import { computed, defineComponent, nextTick, onMounted, ref, watch } from 'vue' import { getPrefixCls } from '../_utils/getPrefixCls' +import Icon from '../icon' export default defineComponent({ name: 'Textarea', + props: { + modelValue: { type: String, default: '222' }, + autosize: { type: [Boolean, Object] as PropType, default: false }, + disabled: Boolean, + readonly: Boolean, + clearable: Boolean, + showCount: Boolean, + maxlength: Number, + autoFocus: Boolean, + }, emits: ['update:modelValue'], - setup() { - const prefixCls = getPrefixCls('input') + setup(props, { emit }) { + const prefixCls = getPrefixCls('textarea') + const textareaRef = ref(null) + const inputValue = ref(props.modelValue || '') + + /** textarea 高度自适应 */ + const resizeTextarea = () => { + const el = textareaRef.value + if (!el || !props.autosize) + return + + el.style.height = 'auto' + + const style = getComputedStyle(el) + const border = Number.parseInt(style.borderTopWidth) + Number.parseInt(style.borderBottomWidth) + let height = el.scrollHeight + border + + if (typeof props.autosize === 'object') { + const lineHeight = Number.parseInt(style.lineHeight || '20', 10) + const { minRows, maxRows } = props.autosize + if (minRows) + height = Math.max(height, lineHeight * minRows + border) + if (maxRows) + height = Math.min(height, lineHeight * maxRows + border) + } + + el.style.height = `${height}px` + } + + /** 同步父组件 modelValue */ + watch( + () => props.modelValue, + (val) => { + inputValue.value = val || '' + nextTick(resizeTextarea) + }, + ) + + /** 动态 autoFocus */ + watch( + () => props.autoFocus, + (val) => { + if (val && textareaRef.value) { + nextTick(() => textareaRef.value!.focus()) + } + }, + { immediate: true }, + ) + + /** 更新值 */ + const updateValue = (val: string) => { + if (props.maxlength) + val = val.slice(0, props.maxlength) + inputValue.value = val + emit('update:modelValue', val) + nextTick(resizeTextarea) + } + + /** 清空 */ + const clearValue = () => { + updateValue('') + if (textareaRef.value) + textareaRef.value.focus() + } + + const countText = computed(() => { + const len = inputValue.value.length + return props.maxlength ? `${len} / ${props.maxlength}` : `${len}` + }) + + onMounted(() => nextTick(() => { + resizeTextarea() + if (props.autoFocus && textareaRef.value) + textareaRef.value.focus() + })) return () => { + const value = inputValue.value + return (
-