u
This commit is contained in:
1 parent
14f9844430
commit
785bce1907
27 files changed
+1015
-139
No files matched your search
+9
-1
@@ -29,12 +29,20 @@
|
|||||||
"export default defineComponent({",
|
"export default defineComponent({",
|
||||||
" name: '${1:AoComponent}',",
|
" name: '${1:AoComponent}',",
|
||||||
" props: {",
|
" props: {",
|
||||||
|
" class: {",
|
||||||
|
" type: [String, Array, Object],",
|
||||||
|
" default: '',",
|
||||||
|
" },",
|
||||||
|
" style: {",
|
||||||
|
" type: Object,",
|
||||||
|
" default: () => ({}),",
|
||||||
|
" },",
|
||||||
" },",
|
" },",
|
||||||
" emits: [],",
|
" emits: [],",
|
||||||
" setup(props, { slots, emit }) {",
|
" setup(props, { slots, emit }) {",
|
||||||
" const prefixCls = getPrefixCls('${2:component}');",
|
" const prefixCls = getPrefixCls('${2:component}');",
|
||||||
" return () => (",
|
" return () => (",
|
||||||
" <div class={prefixCls}>",
|
" <div class={[prefixCls, props.class]} style={{ ...props.style }}>",
|
||||||
" {slots.default?.()}",
|
" {slots.default?.()}",
|
||||||
" </div>",
|
" </div>",
|
||||||
" );",
|
" );",
|
||||||
|
|||||||
@@ -13,30 +13,48 @@ $default-color-hover: var(--ao-default-color-hover); // hover态
|
|||||||
$default-color-focus: var(--ao-default-color-focus); // focus态,包括鼠标和键盘
|
$default-color-focus: var(--ao-default-color-focus); // focus态,包括鼠标和键盘
|
||||||
$default-color-active: var(--ao-default-color-active); // 点击态
|
$default-color-active: var(--ao-default-color-active); // 点击态
|
||||||
$default-color-disabled: var(--ao-default-color-disabled); // 禁用态
|
$default-color-disabled: var(--ao-default-color-disabled); // 禁用态
|
||||||
|
$default-color-light: var(--ao-default-color-light);
|
||||||
|
$default-color-light-active: var(--ao-default-color-light-active);
|
||||||
|
|
||||||
// 基础颜色的扩展 用于 hover / 聚焦 / 禁用 / 点击 等状态
|
// 基础颜色的扩展 用于 hover / 聚焦 / 禁用 / 点击 等状态
|
||||||
$primary-color-hover: var(--ao-primary-color-hover); // hover态
|
$primary-color-hover: var(--ao-primary-color-hover); // hover态
|
||||||
$primary-color-focus: var(--ao-primary-color-focus); // focus态,包括鼠标和键盘
|
$primary-color-focus: var(--ao-primary-color-focus); // focus态,包括鼠标和键盘
|
||||||
$primary-color-active: var(--ao-primary-color-active); // 点击态
|
$primary-color-active: var(--ao-primary-color-active); // 点击态
|
||||||
$primary-color-disabled: var(--ao-primary-color-disabled); // 禁用态
|
$primary-color-disabled: var(--ao-primary-color-disabled); // 禁用态
|
||||||
|
$primary-color-light: var(--ao-primary-color-light);
|
||||||
|
$primary-color-light-active: var(--ao-primary-color-light-active);
|
||||||
|
|
||||||
// 警告色扩展
|
// 警告色扩展
|
||||||
$warning-color-hover: var(--ao-warning-color-hover);
|
$warning-color-hover: var(--ao-warning-color-hover);
|
||||||
$warning-color-focus: var(--ao-warning-color-focus);
|
$warning-color-focus: var(--ao-warning-color-focus);
|
||||||
$warning-color-active: var(--ao-warning-color-active);
|
$warning-color-active: var(--ao-warning-color-active);
|
||||||
$warning-color-disabled: var(--ao-warning-color-disabled);
|
$warning-color-disabled: var(--ao-warning-color-disabled);
|
||||||
|
$warning-color-light: var(--ao-warning-color-light);
|
||||||
|
$warning-color-light-active: var(--ao-warning-color-light-active);
|
||||||
|
|
||||||
// 失败/错误色扩展
|
// 失败/错误色扩展
|
||||||
$danger-color-hover: var(--ao-danger-color-hover);
|
$danger-color-hover: var(--ao-danger-color-hover);
|
||||||
$danger-color-focus: var(--ao-danger-color-focus);
|
$danger-color-focus: var(--ao-danger-color-focus);
|
||||||
$danger-color-active: var(--ao-danger-color-active);
|
$danger-color-active: var(--ao-danger-color-active);
|
||||||
$danger-color-disabled: var(--ao-danger-color-disabled);
|
$danger-color-disabled: var(--ao-danger-color-disabled);
|
||||||
|
$danger-color-light: var(--ao-danger-color-light);
|
||||||
|
$danger-color-light-active: var(--ao-danger-color-light-active);
|
||||||
|
|
||||||
// 成功色扩展
|
// 成功色扩展
|
||||||
$success-color-hover: var(--ao-success-color-hover);
|
$success-color-hover: var(--ao-success-color-hover);
|
||||||
$success-color-focus: var(--ao-success-color-focus);
|
$success-color-focus: var(--ao-success-color-focus);
|
||||||
$success-color-active: var(--ao-success-color-active);
|
$success-color-active: var(--ao-success-color-active);
|
||||||
$success-color-disabled: var(--ao-success-color-disabled);
|
$success-color-disabled: var(--ao-success-color-disabled);
|
||||||
|
$success-color-light: var(--ao-success-color-light);
|
||||||
|
$success-color-light-active: var(--ao-success-color-light-active);
|
||||||
|
|
||||||
|
// 状态背景色
|
||||||
|
$status-base-bg-color: var(--ao-status-base-bg-color);
|
||||||
|
$status-anti-bg-color: var(--ao-status-anti-bg-color);
|
||||||
|
$status-info-bg-color: var(--ao-status-info-bg-color);
|
||||||
|
$status-success-bg-color: var(--ao-status-success-bg-color);
|
||||||
|
$status-warning-bg-color: var(--ao-status-warning-bg-color);
|
||||||
|
$status-danger-bg-color: var(--ao-status-danger-bg-color);
|
||||||
|
|
||||||
// 文本颜色
|
// 文本颜色
|
||||||
$text-color-base: var(--ao-text-color-base); // 色彩-文字-主要
|
$text-color-base: var(--ao-text-color-base); // 色彩-文字-主要
|
||||||
|
|||||||
@@ -9,26 +9,43 @@
|
|||||||
--ao-default-color-focus: #505050;
|
--ao-default-color-focus: #505050;
|
||||||
--ao-default-color-active: #5c5c5c;
|
--ao-default-color-active: #5c5c5c;
|
||||||
--ao-default-color-disabled: #2c2c2c;
|
--ao-default-color-disabled: #2c2c2c;
|
||||||
|
--ao-default-color-light: #f3f3f3;
|
||||||
|
--ao-default-color-light-active: #ddd;
|
||||||
|
|
||||||
--ao-primary-color-hover: #2667d4;
|
--ao-primary-color-hover: #2667d4;
|
||||||
--ao-primary-color-focus: #173463;
|
--ao-primary-color-focus: #173463;
|
||||||
--ao-primary-color-active: #699ef5;
|
--ao-primary-color-active: #699ef5;
|
||||||
--ao-primary-color-disabled: #143975;
|
--ao-primary-color-disabled: #143975;
|
||||||
|
--ao-primary-color-light: #1b2f51;
|
||||||
|
--ao-primary-color-light-active: #173463;
|
||||||
|
|
||||||
--ao-warning-color-hover: #a75d2b;
|
--ao-warning-color-hover: #a75d2b;
|
||||||
--ao-warning-color-focus: #582f21;
|
--ao-warning-color-focus: #582f21;
|
||||||
--ao-warning-color-active: #dc7633;
|
--ao-warning-color-active: #dc7633;
|
||||||
--ao-warning-color-disabled: #733c23;
|
--ao-warning-color-disabled: #733c23;
|
||||||
|
--ao-warning-color-light: #4f2a1d;
|
||||||
|
--ao-warning-color-light-active: #582f21;
|
||||||
|
|
||||||
--ao-danger-color-hover: #a03f46;
|
--ao-danger-color-hover: #a03f46;
|
||||||
--ao-danger-color-focus: #5e2a2d;
|
--ao-danger-color-focus: #5e2a2d;
|
||||||
--ao-danger-color-active: #de6670;
|
--ao-danger-color-active: #de6670;
|
||||||
--ao-danger-color-disabled: #703439;
|
--ao-danger-color-disabled: #703439;
|
||||||
|
--ao-danger-color-light: #472324;
|
||||||
|
--ao-danger-color-light-active: #5e2a2d;
|
||||||
|
|
||||||
--ao-success-color-hover: #0d7a55;
|
--ao-success-color-hover: #0d7a55;
|
||||||
--ao-success-color-focus: #1a4230;
|
--ao-success-color-focus: #1a4230;
|
||||||
--ao-success-color-active: #43af8a;
|
--ao-success-color-active: #43af8a;
|
||||||
--ao-success-color-disabled: #17533d;
|
--ao-success-color-disabled: #17533d;
|
||||||
|
--ao-success-color-light: #193a2a;
|
||||||
|
--ao-success-color-light-active: #1a4230;
|
||||||
|
|
||||||
|
--ao-status-base-bg-color: #242424;
|
||||||
|
--ao-status-anti-bg-color: #c6cacd; // 反色,用于tooltip默认背景色
|
||||||
|
--ao-status-info-bg-color: #233448;
|
||||||
|
--ao-status-success-bg-color: #253929;
|
||||||
|
--ao-status-warning-bg-color: #453522;
|
||||||
|
--ao-status-danger-bg-color: #442927;
|
||||||
|
|
||||||
--ao-text-color-base: rgba(255, 255, 255, 90%); /* 主要文字 */
|
--ao-text-color-base: rgba(255, 255, 255, 90%); /* 主要文字 */
|
||||||
--ao-text-color-secondary: rgba(255, 255, 255, 55%); /* 次要文字 / 辅助信息 */
|
--ao-text-color-secondary: rgba(255, 255, 255, 55%); /* 次要文字 / 辅助信息 */
|
||||||
@@ -60,10 +77,9 @@
|
|||||||
// 基础/下层 投影 hover 使用的组件包括:表格 /
|
// 基础/下层 投影 hover 使用的组件包括:表格 /
|
||||||
--ao-shadow-surface: 0 4px 6px rgba(0, 0, 0, 6%), 0 1px 10px rgba(0, 0, 0, 8%), 0 2px 4px rgba(0, 0, 0, 12%);
|
--ao-shadow-surface: 0 4px 6px rgba(0, 0, 0, 6%), 0 1px 10px rgba(0, 0, 0, 8%), 0 2px 4px rgba(0, 0, 0, 12%);
|
||||||
// 中层投影 下拉 使用的组件包括:下拉菜单 / 气泡确认框 / 选择器 /
|
// 中层投影 下拉 使用的组件包括:下拉菜单 / 气泡确认框 / 选择器 /
|
||||||
--ao-shadow-popup: 0 8px 10px rgba(0, 0, 0, 12%), 0 3px 14px rgba(0, 0, 0, 10%), 0 5px 5px rgba(0, 0, 0, 16%);
|
--ao-shadow-popup: 0 0 4px rgba(0, 0, 0, 0.04), 0 0 8px rgba(0, 0, 0, 0.03);
|
||||||
// 上层投影(警示/弹窗)使用的组件包括:全局提示 / 消息通知
|
// 上层投影(警示/弹窗)使用的组件包括:全局提示 / 消息通知
|
||||||
--ao-shadow-overlay: 0 16px 24px rgba(0, 0, 0, 14%), 0 6px 30px rgba(0, 0, 0, 12%), 0 8px 10px rgba(0, 0, 0, 20%);
|
--ao-shadow-overlay: inset 0 0 0 1px hsla(0, 0%, 100%, 0.1), 0 4px 14px rgba(0, 0, 0, 0.25);
|
||||||
|
|
||||||
// 内投影
|
// 内投影
|
||||||
--ao-shadow-inset-top: inset 0 0.5px 0 #5e5e5e;
|
--ao-shadow-inset-top: inset 0 0.5px 0 #5e5e5e;
|
||||||
--ao-shadow-inset-right: inset 0.5px 0 0 #5e5e5e;
|
--ao-shadow-inset-right: inset 0.5px 0 0 #5e5e5e;
|
||||||
|
|||||||
@@ -10,26 +10,43 @@
|
|||||||
--ao-default-color-focus: #cfcfcf;
|
--ao-default-color-focus: #cfcfcf;
|
||||||
--ao-default-color-active: #ababab;
|
--ao-default-color-active: #ababab;
|
||||||
--ao-default-color-disabled: #eeeeee;
|
--ao-default-color-disabled: #eeeeee;
|
||||||
|
--ao-default-color-light: #f3f3f3;
|
||||||
|
--ao-default-color-light-active: #ddd;
|
||||||
|
|
||||||
--ao-primary-color-hover: #366ef4;
|
--ao-primary-color-hover: #366ef4;
|
||||||
--ao-primary-color-focus: #d9e1ff;
|
--ao-primary-color-focus: #d9e1ff;
|
||||||
--ao-primary-color-active: #003cab;
|
--ao-primary-color-active: #003cab;
|
||||||
--ao-primary-color-disabled: #b5c7ff;
|
--ao-primary-color-disabled: #b5c7ff;
|
||||||
|
--ao-primary-color-light: #f2f3ff;
|
||||||
|
--ao-primary-color-light-active: #d9e1ff;
|
||||||
|
|
||||||
--ao-warning-color-hover: #fa9550;
|
--ao-warning-color-hover: #fa9550;
|
||||||
--ao-warning-color-focus: #ffd9c2;
|
--ao-warning-color-focus: #ffd9c2;
|
||||||
--ao-warning-color-active: #be5a00;
|
--ao-warning-color-active: #be5a00;
|
||||||
--ao-warning-color-disabled: #ffb98c;
|
--ao-warning-color-disabled: #ffb98c;
|
||||||
|
--ao-warning-color-light: #fff1e9;
|
||||||
|
--ao-warning-color-light-active: #ffd9c2;
|
||||||
|
|
||||||
--ao-danger-color-hover: #f6685d;
|
--ao-danger-color-hover: #f6685d;
|
||||||
--ao-danger-color-focus: #ffd8d2;
|
--ao-danger-color-focus: #ffd8d2;
|
||||||
--ao-danger-color-active: #ad352f;
|
--ao-danger-color-active: #ad352f;
|
||||||
--ao-danger-color-disabled: #ffb9b0;
|
--ao-danger-color-disabled: #ffb9b0;
|
||||||
|
--ao-danger-color-light: #fff0ed;
|
||||||
|
--ao-danger-color-light-active: #ffd8d2;
|
||||||
|
|
||||||
--ao-success-color-hover: #56c08d;
|
--ao-success-color-hover: #56c08d;
|
||||||
--ao-success-color-focus: #c6f3d7;
|
--ao-success-color-focus: #c6f3d7;
|
||||||
--ao-success-color-active: #008858;
|
--ao-success-color-active: #008858;
|
||||||
--ao-success-color-disabled: #92dab2;
|
--ao-success-color-disabled: #92dab2;
|
||||||
|
--ao-success-color-light: #e3f9e9;
|
||||||
|
--ao-success-color-light-active: #c6f3d7;
|
||||||
|
|
||||||
|
--ao-status-base-bg-color: #fff;
|
||||||
|
--ao-status-anti-bg-color: #41464c; // 反色,用于tooltip默认背景色
|
||||||
|
--ao-status-info-bg-color: #f2f3ff;
|
||||||
|
--ao-status-success-bg-color: #ecf7ec;
|
||||||
|
--ao-status-warning-bg-color: #fff8ea;
|
||||||
|
--ao-status-danger-bg-color: #fef2ed;
|
||||||
|
|
||||||
--ao-text-color-base: rgba(0, 0, 0, 90%); /* 主要文字 */
|
--ao-text-color-base: rgba(0, 0, 0, 90%); /* 主要文字 */
|
||||||
--ao-text-color-secondary: rgba(0, 0, 0, 60%); /* 次要文字 / 辅助信息 */
|
--ao-text-color-secondary: rgba(0, 0, 0, 60%); /* 次要文字 / 辅助信息 */
|
||||||
@@ -61,13 +78,10 @@
|
|||||||
// 基础/下层 投影 hover 使用的组件包括:表格 /
|
// 基础/下层 投影 hover 使用的组件包括:表格 /
|
||||||
--ao-shadow-surface: 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%);
|
--ao-shadow-surface: 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%);
|
||||||
// 中层投影 下拉 使用的组件包括:下拉菜单 / 气泡确认框 / 选择器 /
|
// 中层投影 下拉 使用的组件包括:下拉菜单 / 气泡确认框 / 选择器 /
|
||||||
--ao-shadow-popup:
|
--ao-shadow-popup: 0 0 4px rgba(0, 0, 0, 0.04), 0 0 8px rgba(0, 0, 0, 0.03);
|
||||||
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%);
|
|
||||||
// 上层投影(警示/弹窗)使用的组件包括:全局提示 / 消息通知
|
|
||||||
--ao-shadow-overlay:
|
|
||||||
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%);
|
|
||||||
|
|
||||||
// 内投影
|
// 上层投影(警示/弹窗)使用的组件包括:全局提示 / 消息通知
|
||||||
|
--ao-shadow-overlay: 0 0 1px rgba(0, 0, 0, 0.3), 0 4px 14px rgba(0, 0, 0, 0.1);
|
||||||
--ao-shadow-inset-top: inset 0 0.5px 0 #dcdcdc;
|
--ao-shadow-inset-top: inset 0 0.5px 0 #dcdcdc;
|
||||||
--ao-shadow-inset-right: inset 0.5px 0 0 #dcdcdc;
|
--ao-shadow-inset-right: inset 0.5px 0 0 #dcdcdc;
|
||||||
--ao-shadow-inset-bottom: inset 0 -0.5px 0 #dcdcdc;
|
--ao-shadow-inset-bottom: inset 0 -0.5px 0 #dcdcdc;
|
||||||
|
|||||||
@@ -7,4 +7,7 @@ export { default as Input } from './input'
|
|||||||
export { default as Popconfirm } from './popconfirm'
|
export { default as Popconfirm } from './popconfirm'
|
||||||
export { default as Popup } from './popup'
|
export { default as Popup } from './popup'
|
||||||
export { default as Spin } from './spin'
|
export { default as Spin } from './spin'
|
||||||
|
export { default as Tag } from './tag'
|
||||||
|
export { default as TagGroup } from './tag-group'
|
||||||
export { default as Textarea } from './textarea'
|
export { default as Textarea } from './textarea'
|
||||||
|
export { default as Tooltip } from './tooltip'
|
||||||
@@ -10,3 +10,6 @@
|
|||||||
@use './message/index.scss' as *;
|
@use './message/index.scss' as *;
|
||||||
@use './notification/index.scss' as *;
|
@use './notification/index.scss' as *;
|
||||||
@use './drawer/index.scss' as *;
|
@use './drawer/index.scss' as *;
|
||||||
|
@use './tooltip/index.scss' as *;
|
||||||
|
@use './tag/index.scss' as *;
|
||||||
|
@use './tag-group/index.scss' as *;
|
||||||
@@ -21,6 +21,8 @@ function showMessageType(type: any) {
|
|||||||
message.success({
|
message.success({
|
||||||
message: `这里是 ${type} 提示`,
|
message: `这里是 ${type} 提示`,
|
||||||
type,
|
type,
|
||||||
|
duration: 0,
|
||||||
|
theme: 'light',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -76,6 +78,9 @@ function showMessageType(type: any) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<AButton status="primary" @click="showMessageType('default')">
|
||||||
|
default
|
||||||
|
</AButton>
|
||||||
<AButton status="primary" @click="showMessageType('info')">
|
<AButton status="primary" @click="showMessageType('info')">
|
||||||
info
|
info
|
||||||
</AButton>
|
</AButton>
|
||||||
@@ -85,7 +90,7 @@ function showMessageType(type: any) {
|
|||||||
<AButton status="primary" @click="showMessageType('warning')">
|
<AButton status="primary" @click="showMessageType('warning')">
|
||||||
warning
|
warning
|
||||||
</AButton>
|
</AButton>
|
||||||
<AButton status="primary" @click="showMessageType('error')">
|
<AButton status="primary" @click="showMessageType('danger')">
|
||||||
error
|
error
|
||||||
</AButton>
|
</AButton>
|
||||||
<AButton status="primary" @click="showMessageType('loading')">
|
<AButton status="primary" @click="showMessageType('loading')">
|
||||||
|
|||||||
@@ -47,23 +47,35 @@ $message-prefix: #{$prefix}-message;
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-info {
|
&-info {
|
||||||
|
.#{$message-prefix}-icon {
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-success {
|
&-success {
|
||||||
|
.#{$message-prefix}-icon {
|
||||||
color: $success-color;
|
color: $success-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-warning {
|
&-warning {
|
||||||
|
.#{$message-prefix}-icon {
|
||||||
color: $warning-color;
|
color: $warning-color;
|
||||||
}
|
}
|
||||||
&-error {
|
}
|
||||||
|
&-danger {
|
||||||
|
.#{$message-prefix}-icon {
|
||||||
color: $danger-color;
|
color: $danger-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-question {
|
&-question {
|
||||||
|
.#{$message-prefix}-icon {
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-loading {
|
&-loading {
|
||||||
|
.#{$message-prefix}-icon {
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-placement {
|
&-placement {
|
||||||
&-top {
|
&-top {
|
||||||
top: 20px;
|
top: 20px;
|
||||||
@@ -128,3 +140,27 @@ $message-prefix: #{$prefix}-message;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.#{$message-prefix}-theme-normal.#{$message-prefix} {
|
||||||
|
background-color: $status-base-bg-color;
|
||||||
|
}
|
||||||
|
.#{$message-prefix}-theme-light.#{$message-prefix}-default {
|
||||||
|
background-color: $status-base-bg-color;
|
||||||
|
}
|
||||||
|
.#{$message-prefix}-theme-light.#{$message-prefix}-info {
|
||||||
|
background-color: $status-info-bg-color;
|
||||||
|
}
|
||||||
|
.#{$message-prefix}-theme-light.#{$message-prefix}-success {
|
||||||
|
background-color: $status-success-bg-color;
|
||||||
|
}
|
||||||
|
.#{$message-prefix}-theme-light.#{$message-prefix}-warning {
|
||||||
|
background-color: $status-warning-bg-color;
|
||||||
|
}
|
||||||
|
.#{$message-prefix}-theme-light.#{$message-prefix}-danger {
|
||||||
|
background-color: $status-danger-bg-color;
|
||||||
|
}
|
||||||
|
.#{$message-prefix}-theme-light.#{$message-prefix}-loading {
|
||||||
|
background-color: $status-info-bg-color;
|
||||||
|
}
|
||||||
|
.#{$message-prefix}-theme-light.#{$message-prefix}-question {
|
||||||
|
background-color: $status-info-bg-color;
|
||||||
|
}
|
||||||
@@ -14,11 +14,13 @@ type Placement
|
|||||||
| 'bottom-end'
|
| 'bottom-end'
|
||||||
| 'center'
|
| 'center'
|
||||||
|
|
||||||
type MessageType = 'info' | 'success' | 'warning' | 'error' | 'loading' | 'question'
|
type MessageType = 'default' | 'info' | 'success' | 'warning' | 'danger' | 'loading' | 'question'
|
||||||
|
type MessageTheme = 'normal' | 'light'
|
||||||
|
|
||||||
interface MessageOptions {
|
interface MessageOptions {
|
||||||
message: string | VNode | (() => VNode)
|
message: string | VNode | (() => VNode)
|
||||||
type?: MessageType
|
type?: MessageType
|
||||||
|
theme?: MessageTheme
|
||||||
placement?: Placement
|
placement?: Placement
|
||||||
duration?: number
|
duration?: number
|
||||||
showClose?: boolean
|
showClose?: boolean
|
||||||
@@ -30,10 +32,11 @@ interface MessageHandle {
|
|||||||
|
|
||||||
interface MessageFn {
|
interface MessageFn {
|
||||||
(msg: string | MessageOptions): MessageHandle
|
(msg: string | MessageOptions): MessageHandle
|
||||||
|
open: (msg: string | MessageOptions) => MessageHandle
|
||||||
info: (msg: string | MessageOptions) => MessageHandle
|
info: (msg: string | MessageOptions) => MessageHandle
|
||||||
success: (msg: string | MessageOptions) => MessageHandle
|
success: (msg: string | MessageOptions) => MessageHandle
|
||||||
warning: (msg: string | MessageOptions) => MessageHandle
|
warning: (msg: string | MessageOptions) => MessageHandle
|
||||||
error: (msg: string | MessageOptions) => MessageHandle
|
danger: (msg: string | MessageOptions) => MessageHandle
|
||||||
closeAll: () => void
|
closeAll: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,13 +71,13 @@ function getTransform(placement: Placement, hidden: boolean) {
|
|||||||
export function useMessage(): MessageFn {
|
export function useMessage(): MessageFn {
|
||||||
const createMessage = (
|
const createMessage = (
|
||||||
msg: string | MessageOptions,
|
msg: string | MessageOptions,
|
||||||
defaultType: MessageType = 'info',
|
defaultType: MessageType = 'default',
|
||||||
): MessageHandle => {
|
): MessageHandle => {
|
||||||
const opts: MessageOptions = typeof msg === 'string'
|
const opts: MessageOptions = typeof msg === 'string'
|
||||||
? { message: msg, type: defaultType }
|
? { message: msg, type: defaultType }
|
||||||
: { ...msg, type: msg.type || defaultType }
|
: { ...msg, type: msg.type || defaultType }
|
||||||
|
|
||||||
const { message, type, placement = 'top', duration = 3000, showClose } = opts
|
const { message, type, theme, placement = 'top', duration = 3000, showClose } = opts
|
||||||
const container = getContainer(placement)
|
const container = getContainer(placement)
|
||||||
let timer: number | undefined
|
let timer: number | undefined
|
||||||
let handle: MessageHandle
|
let handle: MessageHandle
|
||||||
@@ -83,6 +86,7 @@ export function useMessage(): MessageFn {
|
|||||||
render() {
|
render() {
|
||||||
return h(MessageItem, {
|
return h(MessageItem, {
|
||||||
type,
|
type,
|
||||||
|
theme,
|
||||||
message,
|
message,
|
||||||
placement,
|
placement,
|
||||||
showClose,
|
showClose,
|
||||||
@@ -140,10 +144,11 @@ export function useMessage(): MessageFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const api = ((msg: string | MessageOptions) => createMessage(msg)) as MessageFn
|
const api = ((msg: string | MessageOptions) => createMessage(msg)) as MessageFn
|
||||||
|
api.open = msg => createMessage(msg, 'default')
|
||||||
api.info = msg => createMessage(msg, 'info')
|
api.info = msg => createMessage(msg, 'info')
|
||||||
api.success = msg => createMessage(msg, 'success')
|
api.success = msg => createMessage(msg, 'success')
|
||||||
api.warning = msg => createMessage(msg, 'warning')
|
api.warning = msg => createMessage(msg, 'warning')
|
||||||
api.error = msg => createMessage(msg, 'error')
|
api.danger = msg => createMessage(msg, 'danger')
|
||||||
api.closeAll = () => {
|
api.closeAll = () => {
|
||||||
instances.slice().forEach(instance => instance.close())
|
instances.slice().forEach(instance => instance.close())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ const prefixCls = getPrefixCls('message')
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MessageItem',
|
name: 'MessageItem',
|
||||||
props: {
|
props: {
|
||||||
type: { type: String, default: 'info' },
|
type: { type: String, default: 'default' },
|
||||||
|
theme: { type: String, default: 'normal' },
|
||||||
message: {
|
message: {
|
||||||
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
|
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
|
||||||
required: true,
|
required: true,
|
||||||
@@ -23,7 +24,7 @@ export default defineComponent({
|
|||||||
setup(props) {
|
setup(props) {
|
||||||
const iconMap: Record<string, string> = {
|
const iconMap: Record<string, string> = {
|
||||||
success: 'ix:success-filled',
|
success: 'ix:success-filled',
|
||||||
error: 'ix:error-filled',
|
danger: 'ix:error-filled',
|
||||||
warning: 'ix:warning-filled',
|
warning: 'ix:warning-filled',
|
||||||
info: 'ix:info-filled',
|
info: 'ix:info-filled',
|
||||||
question: 'ix:question-filled',
|
question: 'ix:question-filled',
|
||||||
@@ -36,14 +37,16 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class={`${prefixCls}`}
|
class={`${prefixCls} ${prefixCls}-theme-${props.theme ?? 'normal'} ${prefixCls}-${props.type ?? 'default'}`}
|
||||||
>
|
>
|
||||||
|
{props.type !== 'default' && (
|
||||||
<Icon
|
<Icon
|
||||||
icon={iconMap[props.type ?? 'info']}
|
icon={iconMap[props.type ?? 'info']}
|
||||||
size={20}
|
size={20}
|
||||||
class={`${prefixCls}-icon ${prefixCls}-${props.type ?? 'info'}`}
|
class={`${prefixCls}-icon`}
|
||||||
spin={props.type === 'loading'}
|
spin={props.type === 'loading'}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<span class={`${prefixCls}-message`}>
|
<span class={`${prefixCls}-message`}>
|
||||||
{renderMessage(props.message)}
|
{renderMessage(props.message)}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,59 +1,85 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useNotification } from '@ao/ao-design'
|
import { useNotification } from '@ao/ao-design'
|
||||||
import { h } from 'vue'
|
|
||||||
|
|
||||||
const notification = useNotification()
|
const notification = useNotification()
|
||||||
|
|
||||||
function showCustomMessage() {
|
function showNotification(placement: any) {
|
||||||
notification.success({
|
notification.success({
|
||||||
title: '自定义消息',
|
title: `这里是 ${placement} 标题`,
|
||||||
message: () =>
|
message: `这里是 ${placement} 提示`,
|
||||||
h('div', { style: { color: 'red', position: 'relative' } }, [
|
placement,
|
||||||
h('p', {}, '这里是自定义内容,可以是任意 VNode'),
|
})
|
||||||
h('strong', {}, '加粗文本'),
|
}
|
||||||
// 右下角按钮容器
|
function closeOne() {
|
||||||
h(
|
|
||||||
'div',
|
}
|
||||||
{
|
|
||||||
style: {
|
function showNotificationType(type: any) {
|
||||||
position: 'absolute',
|
notification.success({
|
||||||
bottom: '4px',
|
theme: 'light',
|
||||||
right: '4px',
|
title: `这里是 ${type} 标题`,
|
||||||
display: 'flex',
|
message: `这里是 ${type} 提示`,
|
||||||
gap: '4px',
|
type,
|
||||||
},
|
duration: 0,
|
||||||
},
|
|
||||||
[
|
|
||||||
h(
|
|
||||||
'button',
|
|
||||||
{
|
|
||||||
style: { fontSize: '12px', padding: '2px 6px' },
|
|
||||||
onClick: () => alert('Button A clicked'),
|
|
||||||
},
|
|
||||||
'A',
|
|
||||||
),
|
|
||||||
h(
|
|
||||||
'button',
|
|
||||||
{
|
|
||||||
style: { fontSize: '12px', padding: '2px 6px' },
|
|
||||||
onClick: () => alert('Button B clicked'),
|
|
||||||
},
|
|
||||||
'B',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
type: 'success',
|
|
||||||
showClose: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="demo">
|
<div class="demo">
|
||||||
<AButton status="primary" @click="showCustomMessage">
|
<div class="row">
|
||||||
自定义 h 函数消息
|
<AButton status="primary" @click="showNotification('top-start')">
|
||||||
|
Top Start
|
||||||
</AButton>
|
</AButton>
|
||||||
|
<AButton status="primary" @click="showNotification('top-end')">
|
||||||
|
Top End
|
||||||
|
</AButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<AButton status="primary" @click="showNotification('bottom-start')">
|
||||||
|
Bottom Start
|
||||||
|
</AButton>
|
||||||
|
<AButton status="primary" @click="showNotification('bottom-end')">
|
||||||
|
Bottom End
|
||||||
|
</AButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<AButton status="primary" @click="notification.closeAll">
|
||||||
|
Close All
|
||||||
|
</AButton>
|
||||||
|
|
||||||
|
<AButton
|
||||||
|
status="primary" @click="closeOne"
|
||||||
|
>
|
||||||
|
Show No Close
|
||||||
|
</AButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<AButton status="primary" @click="showNotificationType('default')">
|
||||||
|
default
|
||||||
|
</AButton>
|
||||||
|
<AButton status="primary" @click="showNotificationType('info')">
|
||||||
|
info
|
||||||
|
</AButton>
|
||||||
|
<AButton status="primary" @click="showNotificationType('success')">
|
||||||
|
success
|
||||||
|
</AButton>
|
||||||
|
<AButton status="primary" @click="showNotificationType('warning')">
|
||||||
|
warning
|
||||||
|
</AButton>
|
||||||
|
<AButton status="primary" @click="showNotificationType('danger')">
|
||||||
|
error
|
||||||
|
</AButton>
|
||||||
|
<AButton status="primary" @click="showNotificationType('loading')">
|
||||||
|
loading
|
||||||
|
</AButton>
|
||||||
|
<AButton status="primary" @click="showNotificationType('question')">
|
||||||
|
question
|
||||||
|
</AButton>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -65,4 +91,9 @@ function showCustomMessage() {
|
|||||||
gap: 16px;
|
gap: 16px;
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -24,7 +24,6 @@ $notification-prefix: #{$prefix}-notification;
|
|||||||
border: 0;
|
border: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: #ecf7ec;
|
|
||||||
|
|
||||||
&-icon {
|
&-icon {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -47,8 +46,6 @@ $notification-prefix: #{$prefix}-notification;
|
|||||||
&-title {
|
&-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1;
|
|
||||||
|
|
||||||
small {
|
small {
|
||||||
margin: 0px 6px;
|
margin: 0px 6px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -76,27 +73,36 @@ $notification-prefix: #{$prefix}-notification;
|
|||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-footer {
|
|
||||||
}
|
|
||||||
|
|
||||||
&-info {
|
&-info {
|
||||||
|
.#{$notification-prefix}-icon {
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-success {
|
&-success {
|
||||||
|
.#{$notification-prefix}-icon {
|
||||||
color: $success-color;
|
color: $success-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-warning {
|
&-warning {
|
||||||
|
.#{$notification-prefix}-icon {
|
||||||
color: $warning-color;
|
color: $warning-color;
|
||||||
}
|
}
|
||||||
&-error {
|
}
|
||||||
|
&-danger {
|
||||||
|
.#{$notification-prefix}-icon {
|
||||||
color: $danger-color;
|
color: $danger-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-question {
|
&-question {
|
||||||
|
.#{$notification-prefix}-icon {
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&-loading {
|
&-loading {
|
||||||
|
.#{$notification-prefix}-icon {
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&-placement {
|
&-placement {
|
||||||
&-top-start {
|
&-top-start {
|
||||||
@@ -125,3 +131,27 @@ $notification-prefix: #{$prefix}-notification;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.#{$notification-prefix}-theme-normal.#{$notification-prefix} {
|
||||||
|
background-color: $status-base-bg-color;
|
||||||
|
}
|
||||||
|
.#{$notification-prefix}-theme-light.#{$notification-prefix}-default {
|
||||||
|
background-color: $status-base-bg-color;
|
||||||
|
}
|
||||||
|
.#{$notification-prefix}-theme-light.#{$notification-prefix}-info {
|
||||||
|
background-color: $status-info-bg-color;
|
||||||
|
}
|
||||||
|
.#{$notification-prefix}-theme-light.#{$notification-prefix}-success {
|
||||||
|
background-color: $status-success-bg-color;
|
||||||
|
}
|
||||||
|
.#{$notification-prefix}-theme-light.#{$notification-prefix}-warning {
|
||||||
|
background-color: $status-warning-bg-color;
|
||||||
|
}
|
||||||
|
.#{$notification-prefix}-theme-light.#{$notification-prefix}-danger {
|
||||||
|
background-color: $status-danger-bg-color;
|
||||||
|
}
|
||||||
|
.#{$notification-prefix}-theme-light.#{$notification-prefix}-loading {
|
||||||
|
background-color: $status-info-bg-color;
|
||||||
|
}
|
||||||
|
.#{$notification-prefix}-theme-light.#{$notification-prefix}-question {
|
||||||
|
background-color: $status-info-bg-color;
|
||||||
|
}
|
||||||
@@ -9,13 +9,14 @@ type Placement
|
|||||||
| 'bottom-start'
|
| 'bottom-start'
|
||||||
| 'bottom-end'
|
| 'bottom-end'
|
||||||
|
|
||||||
type NotificationType = 'info' | 'success' | 'warning' | 'error' | 'loading' | 'question'
|
type NotificationType = 'default' | 'info' | 'success' | 'warning' | 'danger' | 'loading' | 'question'
|
||||||
|
type NotificationTheme = 'normal' | 'light'
|
||||||
|
|
||||||
interface NotificationOptions {
|
interface NotificationOptions {
|
||||||
message: string | VNode | (() => VNode)
|
message: string | VNode | (() => VNode)
|
||||||
|
|
||||||
title: string
|
title: string
|
||||||
subTitle?: string
|
subTitle?: string
|
||||||
|
theme?: NotificationTheme
|
||||||
type?: NotificationType
|
type?: NotificationType
|
||||||
placement?: Placement
|
placement?: Placement
|
||||||
duration?: number
|
duration?: number
|
||||||
@@ -28,10 +29,11 @@ interface NotificationHandle {
|
|||||||
|
|
||||||
interface MessageFn {
|
interface MessageFn {
|
||||||
(msg: NotificationOptions): NotificationHandle
|
(msg: NotificationOptions): NotificationHandle
|
||||||
|
open: (msg: NotificationOptions) => NotificationHandle
|
||||||
info: (msg: NotificationOptions) => NotificationHandle
|
info: (msg: NotificationOptions) => NotificationHandle
|
||||||
success: (msg: NotificationOptions) => NotificationHandle
|
success: (msg: NotificationOptions) => NotificationHandle
|
||||||
warning: (msg: NotificationOptions) => NotificationHandle
|
warning: (msg: NotificationOptions) => NotificationHandle
|
||||||
error: (msg: NotificationOptions) => NotificationHandle
|
danger: (msg: NotificationOptions) => NotificationHandle
|
||||||
closeAll: () => void
|
closeAll: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,9 +67,9 @@ function getTransform(placement: Placement, hidden: boolean) {
|
|||||||
export function useNotification(): MessageFn {
|
export function useNotification(): MessageFn {
|
||||||
const createNotification = (
|
const createNotification = (
|
||||||
opts: NotificationOptions,
|
opts: NotificationOptions,
|
||||||
defaultType: NotificationType = 'info',
|
defaultType: NotificationType = 'default',
|
||||||
): NotificationHandle => {
|
): NotificationHandle => {
|
||||||
const { message, title, subTitle, type = defaultType, placement = 'top-end', duration = 3000, showClose } = opts
|
const { message, title, subTitle, type = defaultType, theme, placement = 'top-end', duration = 3000, showClose } = opts
|
||||||
|
|
||||||
const container = getContainer(placement)
|
const container = getContainer(placement)
|
||||||
let timer: number | undefined
|
let timer: number | undefined
|
||||||
@@ -77,6 +79,7 @@ export function useNotification(): MessageFn {
|
|||||||
render() {
|
render() {
|
||||||
return h(MessageItem, {
|
return h(MessageItem, {
|
||||||
type,
|
type,
|
||||||
|
theme,
|
||||||
title,
|
title,
|
||||||
subTitle,
|
subTitle,
|
||||||
message,
|
message,
|
||||||
@@ -136,10 +139,11 @@ export function useNotification(): MessageFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const api = ((msg: NotificationOptions) => createNotification(msg)) as MessageFn
|
const api = ((msg: NotificationOptions) => createNotification(msg)) as MessageFn
|
||||||
|
api.open = msg => createNotification(msg, 'default')
|
||||||
api.info = msg => createNotification(msg, 'info')
|
api.info = msg => createNotification(msg, 'info')
|
||||||
api.success = msg => createNotification(msg, 'success')
|
api.success = msg => createNotification(msg, 'success')
|
||||||
api.warning = msg => createNotification(msg, 'warning')
|
api.warning = msg => createNotification(msg, 'warning')
|
||||||
api.error = msg => createNotification(msg, 'error')
|
api.danger = msg => createNotification(msg, 'danger')
|
||||||
api.closeAll = () => {
|
api.closeAll = () => {
|
||||||
instances.slice().forEach(instance => instance.close())
|
instances.slice().forEach(instance => instance.close())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ const prefixCls = getPrefixCls('notification')
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'NotificationItem',
|
name: 'NotificationItem',
|
||||||
props: {
|
props: {
|
||||||
type: { type: String, default: 'info' },
|
type: { type: String, default: 'default' },
|
||||||
|
theme: { type: String, default: 'normal' },
|
||||||
title: { type: String, required: true },
|
title: { type: String, required: true },
|
||||||
message: {
|
message: {
|
||||||
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
|
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
|
||||||
@@ -25,7 +26,7 @@ export default defineComponent({
|
|||||||
setup(props) {
|
setup(props) {
|
||||||
const iconMap: Record<string, string> = {
|
const iconMap: Record<string, string> = {
|
||||||
success: 'ix:success-filled',
|
success: 'ix:success-filled',
|
||||||
error: 'ix:error-filled',
|
danger: 'ix:error-filled',
|
||||||
warning: 'ix:warning-filled',
|
warning: 'ix:warning-filled',
|
||||||
info: 'ix:info-filled',
|
info: 'ix:info-filled',
|
||||||
question: 'ix:question-filled',
|
question: 'ix:question-filled',
|
||||||
@@ -38,15 +39,16 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class={`${prefixCls}`}
|
class={`${prefixCls} ${prefixCls}-theme-${props.theme ?? 'normal'} ${prefixCls}-${props.type ?? 'info'}`}
|
||||||
>
|
>
|
||||||
|
{props.type !== 'default' && (
|
||||||
<Icon
|
<Icon
|
||||||
icon={iconMap[props.type ?? 'info']}
|
icon={iconMap[props.type ?? 'info']}
|
||||||
size={22}
|
size={22}
|
||||||
class={`${prefixCls}-icon ${prefixCls}-${props.type ?? 'info'}`}
|
class={`${prefixCls}-icon`}
|
||||||
spin={props.type === 'loading'}
|
spin={props.type === 'loading'}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<div class={`${prefixCls}-main`}>
|
<div class={`${prefixCls}-main`}>
|
||||||
<div class={`${prefixCls}-title-wrapper`}>
|
<div class={`${prefixCls}-title-wrapper`}>
|
||||||
<span class={`${prefixCls}-title`}>
|
<span class={`${prefixCls}-title`}>
|
||||||
|
|||||||
@@ -23,14 +23,16 @@ $popup-prefix: '#{$prefix}-popup';
|
|||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background: $bg-color-container;
|
background-color: $bg-color-container;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
transform-origin: center;
|
transform-origin: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-content {
|
&-content {
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上方弹出,箭头在底部
|
// 上方弹出,箭头在底部
|
||||||
&[data-popup-placement^='top'] > &-arrow {
|
&[data-popup-placement^='top'] > &-arrow {
|
||||||
bottom: -4px;
|
bottom: -4px;
|
||||||
|
|||||||
@@ -53,11 +53,11 @@ export default defineComponent({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
popupClass: {
|
class: {
|
||||||
type: [String, Array, Object],
|
type: [String, Array, Object],
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
popupStyle: {
|
style: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
@@ -65,6 +65,8 @@ export default defineComponent({
|
|||||||
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
|
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
showDelay: { type: Number, default: 0 },
|
||||||
|
hideDelay: { type: Number, default: 0 },
|
||||||
},
|
},
|
||||||
emits: ['update:visible'],
|
emits: ['update:visible'],
|
||||||
setup(props, { slots, emit }) {
|
setup(props, { slots, emit }) {
|
||||||
@@ -75,6 +77,10 @@ export default defineComponent({
|
|||||||
const arrowRef = ref<HTMLElement | null>(null) // 箭头引用
|
const arrowRef = ref<HTMLElement | null>(null) // 箭头引用
|
||||||
const localVisible = ref(props.visible)
|
const localVisible = ref(props.visible)
|
||||||
const hasRendered = ref(props.visible)
|
const hasRendered = ref(props.visible)
|
||||||
|
// 定时器
|
||||||
|
let showTimer: number | null = null
|
||||||
|
let hideTimer: number | null = null
|
||||||
|
|
||||||
let cleanup: (() => void) | null = null
|
let cleanup: (() => void) | null = null
|
||||||
|
|
||||||
const { floatingStyles, middlewareData, placement, update } = useFloating(
|
const { floatingStyles, middlewareData, placement, update } = useFloating(
|
||||||
@@ -135,43 +141,65 @@ export default defineComponent({
|
|||||||
floatEl.style.width = `${triggerEl.offsetWidth}px`
|
floatEl.style.width = `${triggerEl.offsetWidth}px`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const clearTimers = () => {
|
||||||
|
if (showTimer) {
|
||||||
|
clearTimeout(showTimer)
|
||||||
|
showTimer = null
|
||||||
|
}
|
||||||
|
if (hideTimer) {
|
||||||
|
clearTimeout(hideTimer)
|
||||||
|
hideTimer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const showPopup = async () => {
|
const showPopup = async () => {
|
||||||
|
clearTimers()
|
||||||
|
showTimer = window.setTimeout(async () => {
|
||||||
if (!hasRendered.value)
|
if (!hasRendered.value)
|
||||||
hasRendered.value = true
|
hasRendered.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
fitFloatingWidth()
|
fitFloatingWidth()
|
||||||
localVisible.value = true
|
localVisible.value = true
|
||||||
|
|
||||||
setupAutoUpdate()
|
setupAutoUpdate()
|
||||||
emit('update:visible', true)
|
emit('update:visible', true)
|
||||||
|
}, props.showDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
const hidePopup = async () => {
|
const hidePopup = async () => {
|
||||||
|
clearTimers()
|
||||||
|
hideTimer = window.setTimeout(() => {
|
||||||
localVisible.value = false
|
localVisible.value = false
|
||||||
|
|
||||||
clearAutoUpdate()
|
clearAutoUpdate()
|
||||||
emit('update:visible', false)
|
emit('update:visible', false)
|
||||||
|
}, props.hideDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
const togglePopup = async () => {
|
const togglePopup = async () => {
|
||||||
|
clearTimers()
|
||||||
|
|
||||||
if (!hasRendered.value)
|
if (!hasRendered.value)
|
||||||
hasRendered.value = true
|
hasRendered.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
fitFloatingWidth()
|
fitFloatingWidth()
|
||||||
|
|
||||||
localVisible.value = !localVisible.value
|
if (!localVisible.value) {
|
||||||
|
// 需要显示
|
||||||
|
showTimer = window.setTimeout(async () => {
|
||||||
|
localVisible.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
if (localVisible.value) {
|
|
||||||
setupAutoUpdate()
|
setupAutoUpdate()
|
||||||
|
emit('update:visible', true)
|
||||||
|
}, props.showDelay)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// 需要隐藏
|
||||||
|
hideTimer = window.setTimeout(() => {
|
||||||
|
localVisible.value = false
|
||||||
clearAutoUpdate()
|
clearAutoUpdate()
|
||||||
|
emit('update:visible', false)
|
||||||
|
}, props.hideDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('update:visible', localVisible.value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 事件绑定
|
// 事件绑定
|
||||||
@@ -306,11 +334,11 @@ export default defineComponent({
|
|||||||
<div
|
<div
|
||||||
v-show={localVisible.value}
|
v-show={localVisible.value}
|
||||||
ref={floatingRef}
|
ref={floatingRef}
|
||||||
class={[prefixCls, props.popupClass]}
|
class={[prefixCls, props.class]}
|
||||||
style={{
|
style={{
|
||||||
...floatingStyles.value,
|
...floatingStyles.value,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
...props.popupStyle,
|
...props.style,
|
||||||
}}
|
}}
|
||||||
data-popup-placement={placement.value}
|
data-popup-placement={placement.value}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
@use '../_styles/_variables.scss' as *;
|
||||||
|
@use 'sass:color';
|
||||||
|
|
||||||
|
$tag-prefix: '#{$prefix}-tag';
|
||||||
|
|
||||||
|
$tag-group-prefix: '#{$prefix}-tag-group';
|
||||||
|
|
||||||
|
.#{$tag-group-prefix} {
|
||||||
|
> .#{$tag-prefix}:not(:last-child) {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import type { PropType, VNode } from 'vue'
|
||||||
|
import { cloneVNode, defineComponent, ref } from 'vue'
|
||||||
|
import { getPrefixCls } from '../_utils/getPrefixCls'
|
||||||
|
import Tag from '../tag/index'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'TagGroup',
|
||||||
|
props: {
|
||||||
|
modelValue: { type: Array as PropType<(string | number)[]>, default: () => [] },
|
||||||
|
multiple: { type: Boolean, default: true },
|
||||||
|
options: {
|
||||||
|
type: Array as PropType<Array<{ label: string, value: string | number }>>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
checkedProps: {
|
||||||
|
type: Object as PropType<{
|
||||||
|
type?: string
|
||||||
|
status?: string
|
||||||
|
}>,
|
||||||
|
default: () => ({
|
||||||
|
type: 'solid',
|
||||||
|
status: 'primary',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
uncheckedProps: {
|
||||||
|
type: Object as PropType<{
|
||||||
|
type?: string
|
||||||
|
status?: string
|
||||||
|
}>,
|
||||||
|
default: () => ({
|
||||||
|
type: 'solid',
|
||||||
|
status: 'default',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
class: {
|
||||||
|
type: [String, Array, Object],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: [],
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const prefixCls = getPrefixCls('tag-group')
|
||||||
|
const selectedValues = ref([...props.modelValue])
|
||||||
|
|
||||||
|
const renderSlotTags = () => {
|
||||||
|
const slotNodes = slots.default?.() || []
|
||||||
|
return slotNodes.map((vnode: VNode) => {
|
||||||
|
// 判断是否是 Tag 组件
|
||||||
|
if (vnode.type === Tag) {
|
||||||
|
const value = (vnode.props as any)?.value
|
||||||
|
const checked = selectedValues.value.includes(value)
|
||||||
|
return cloneVNode(vnode, {
|
||||||
|
checked,
|
||||||
|
'type': checked ? props.checkedProps.type : props.uncheckedProps.type,
|
||||||
|
'status': checked ? props.checkedProps.status : props.uncheckedProps.status,
|
||||||
|
'onUpdate:checked': (val: boolean) => handleTagClick(value, val),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return vnode
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<div class={[prefixCls, props.class]} style={{ ...props.style }}>
|
||||||
|
{slots.default?.()}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="demo">
|
||||||
|
<div class="row">
|
||||||
|
<ATag size="small">
|
||||||
|
small
|
||||||
|
</ATag>
|
||||||
|
<ATag size="medium">
|
||||||
|
medium
|
||||||
|
</ATag>
|
||||||
|
<ATag size="large">
|
||||||
|
large
|
||||||
|
</ATag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<ATag shape="round">
|
||||||
|
round
|
||||||
|
</ATag>
|
||||||
|
<ATag shape="mark">
|
||||||
|
mark
|
||||||
|
</ATag>
|
||||||
|
<ATag shape="square">
|
||||||
|
square
|
||||||
|
</ATag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<ATag type="solid">
|
||||||
|
solid
|
||||||
|
</ATag>
|
||||||
|
<ATag type="light">
|
||||||
|
light
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline">
|
||||||
|
outline
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline-light">
|
||||||
|
outline-light
|
||||||
|
</ATag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<ATag type="solid" status="primary">
|
||||||
|
solid
|
||||||
|
</ATag>
|
||||||
|
<ATag type="light" status="primary">
|
||||||
|
light
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline" status="primary">
|
||||||
|
outline
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline-light" status="primary">
|
||||||
|
outline-light
|
||||||
|
</ATag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<ATag type="solid" status="danger">
|
||||||
|
solid
|
||||||
|
</ATag>
|
||||||
|
<ATag type="light" status="danger">
|
||||||
|
light
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline" status="danger">
|
||||||
|
outline
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline-light" status="danger">
|
||||||
|
outline-light
|
||||||
|
</ATag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<ATag type="solid" status="warning">
|
||||||
|
solid
|
||||||
|
</ATag>
|
||||||
|
<ATag type="light" status="warning">
|
||||||
|
light
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline" status="warning">
|
||||||
|
outline
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline-light" status="warning">
|
||||||
|
outline-light
|
||||||
|
</ATag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<ATag type="solid" status="success">
|
||||||
|
solid
|
||||||
|
</ATag>
|
||||||
|
<ATag type="light" status="success">
|
||||||
|
light
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline" status="success">
|
||||||
|
outline
|
||||||
|
</ATag>
|
||||||
|
<ATag type="outline-light" status="success">
|
||||||
|
outline-light
|
||||||
|
</ATag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.demo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
@use '../_styles/_variables.scss' as *;
|
||||||
|
@use 'sass:color';
|
||||||
|
|
||||||
|
$tag-prefix: '#{$prefix}-tag';
|
||||||
|
|
||||||
|
.#{$tag-prefix} {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-radius: $border-color;
|
||||||
|
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
|
|
||||||
|
&-size-large {
|
||||||
|
padding: 0 8px;
|
||||||
|
height: 24px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
&-size-medium {
|
||||||
|
padding: 0 6px;
|
||||||
|
height: 22px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
&-size-small {
|
||||||
|
padding: 0 4px;
|
||||||
|
height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
&-shape-round {
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
&-shape-mark {
|
||||||
|
border-radius: 0px 12px 12px 0;
|
||||||
|
}
|
||||||
|
&-icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
&-close {
|
||||||
|
margin-left: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: filter 0.2s cubic-bezier(0.38, 0, 0.24, 1);
|
||||||
|
|
||||||
|
color: currentColor;
|
||||||
|
filter: brightness(1.2); /* 比父色亮 20% */
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: brightness(0.8); /* 比父色暗 20% */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-type-solid {
|
||||||
|
&.#{$tag-prefix}-status-default {
|
||||||
|
color: $text-color-base;
|
||||||
|
background-color: $default-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-primary {
|
||||||
|
color: $text-color-anti;
|
||||||
|
background-color: $primary-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-success {
|
||||||
|
color: $text-color-anti;
|
||||||
|
background-color: $success-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-warning {
|
||||||
|
color: $text-color-anti;
|
||||||
|
background-color: $warning-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-danger {
|
||||||
|
color: $text-color-anti;
|
||||||
|
background-color: $danger-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-type-light {
|
||||||
|
&.#{$tag-prefix}-status-default {
|
||||||
|
color: $text-color-base;
|
||||||
|
background-color: $default-color-light;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-primary {
|
||||||
|
color: $primary-color;
|
||||||
|
background-color: $primary-color-light;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-success {
|
||||||
|
color: $success-color;
|
||||||
|
background-color: $success-color-light;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-warning {
|
||||||
|
color: $warning-color;
|
||||||
|
background-color: $warning-color-light;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-danger {
|
||||||
|
color: $danger-color;
|
||||||
|
background-color: $danger-color-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-type-outline {
|
||||||
|
&.#{$tag-prefix}-status-default {
|
||||||
|
color: $text-color-base;
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: $default-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-primary {
|
||||||
|
color: $primary-color;
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: $primary-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-success {
|
||||||
|
color: $success-color;
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: $success-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-warning {
|
||||||
|
color: $warning-color;
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: $warning-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-danger {
|
||||||
|
color: $danger-color;
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: $danger-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-type-outline-light {
|
||||||
|
&.#{$tag-prefix}-status-default {
|
||||||
|
color: $text-color-base;
|
||||||
|
background-color: $default-color-light;
|
||||||
|
border-color: $default-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-primary {
|
||||||
|
color: $primary-color;
|
||||||
|
background-color: $primary-color-light;
|
||||||
|
border-color: $primary-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-success {
|
||||||
|
color: $success-color;
|
||||||
|
background-color: $success-color-light;
|
||||||
|
border-color: $success-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-warning {
|
||||||
|
color: $warning-color;
|
||||||
|
background-color: $warning-color-light;
|
||||||
|
border-color: $warning-color;
|
||||||
|
}
|
||||||
|
&.#{$tag-prefix}-status-danger {
|
||||||
|
color: $danger-color;
|
||||||
|
background-color: $danger-color-light;
|
||||||
|
border-color: $danger-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import type { PropType } from 'vue'
|
||||||
|
import { defineComponent, ref } from 'vue'
|
||||||
|
import { getPrefixCls } from '../_utils/getPrefixCls'
|
||||||
|
import Icon from '../icon/index'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Tag',
|
||||||
|
props: {
|
||||||
|
shape: {
|
||||||
|
type: String as PropType<'square' | 'round' | 'mark'>,
|
||||||
|
default: 'square',
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: String as PropType<'small' | 'medium' | 'large'>,
|
||||||
|
default: 'medium',
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String as () => 'solid' | 'light' | 'outline' | 'outline-light',
|
||||||
|
default: 'solid',
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
type: String as () => 'primary' | 'danger' | 'warning' | 'success' | 'default',
|
||||||
|
default: 'default',
|
||||||
|
},
|
||||||
|
showClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
class: {
|
||||||
|
type: [String, Array, Object],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['click', 'close'],
|
||||||
|
setup(props, { slots, emit }) {
|
||||||
|
const prefixCls = getPrefixCls('tag')
|
||||||
|
const visible = ref(true)
|
||||||
|
|
||||||
|
const handleClick = (event: MouseEvent) => {
|
||||||
|
emit('click', event)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = (event: MouseEvent) => {
|
||||||
|
event.stopPropagation()
|
||||||
|
visible.value = false // 点击关闭隐藏 Tag
|
||||||
|
emit('close', event)
|
||||||
|
}
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
visible.value && (
|
||||||
|
<div
|
||||||
|
class={[
|
||||||
|
prefixCls,
|
||||||
|
`${prefixCls}-size-${props.size}`,
|
||||||
|
`${prefixCls}-shape-${props.shape}`,
|
||||||
|
`${prefixCls}-type-${props.type}`,
|
||||||
|
`${prefixCls}-status-${props.status}`,
|
||||||
|
props.class,
|
||||||
|
]}
|
||||||
|
style={{ ...props.style }}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
{props.icon && <Icon icon={props.icon} class={`${prefixCls}-icon`} />}
|
||||||
|
<span>{slots.default?.()}</span>
|
||||||
|
{!props.disabled && props.showClose && (
|
||||||
|
<Icon icon="ix:close" class={`${prefixCls}-close`} onClick={handleClose} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="demo">
|
||||||
|
<div class="row">
|
||||||
|
<ATooltip trigger="click" type="default" content="defaultdefaultdefaultdefaultdefaultdefaultdefaultdefaultdefaultdefaultdefaultdefaultdefaultdefaultdefault">
|
||||||
|
<AButton status="primary">
|
||||||
|
default
|
||||||
|
</AButton>
|
||||||
|
</ATooltip>
|
||||||
|
<ATooltip trigger="click" type="anti" content="anti">
|
||||||
|
<AButton status="primary">
|
||||||
|
anti
|
||||||
|
</AButton>
|
||||||
|
</ATooltip>
|
||||||
|
<ATooltip trigger="click" type="info" content="info">
|
||||||
|
<AButton status="primary">
|
||||||
|
info
|
||||||
|
</AButton>
|
||||||
|
</ATooltip>
|
||||||
|
<ATooltip trigger="click" type="success" content="success">
|
||||||
|
<AButton status="primary">
|
||||||
|
success
|
||||||
|
</AButton>
|
||||||
|
</ATooltip>
|
||||||
|
<ATooltip trigger="click" type="danger" content="danger">
|
||||||
|
<AButton status="primary">
|
||||||
|
danger
|
||||||
|
</AButton>
|
||||||
|
</ATooltip>
|
||||||
|
<ATooltip trigger="click" type="warning" content="warning">
|
||||||
|
<AButton status="primary">
|
||||||
|
warning
|
||||||
|
</AButton>
|
||||||
|
</ATooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.demo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
@use '../_styles/_variables.scss' as *;
|
||||||
|
@use 'sass:color';
|
||||||
|
$popup-prefix: '#{$prefix}-popup';
|
||||||
|
$tooltip-prefix: '#{$prefix}-tooltip';
|
||||||
|
|
||||||
|
.#{$tooltip-prefix} {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: $text-color-base;
|
||||||
|
|
||||||
|
&-wrapper {
|
||||||
|
background-color: $status-base-bg-color;
|
||||||
|
padding: 4px 8px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$popup-prefix}-arrow::before {
|
||||||
|
background-color: $status-base-bg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-default {
|
||||||
|
.#{$tooltip-prefix}-wrapper {
|
||||||
|
background-color: $status-base-bg-color;
|
||||||
|
color: $text-color-base;
|
||||||
|
}
|
||||||
|
.#{$popup-prefix}-arrow::before {
|
||||||
|
background-color: $status-base-bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-anti {
|
||||||
|
.#{$tooltip-prefix}-wrapper {
|
||||||
|
background-color: $status-anti-bg-color;
|
||||||
|
color: $text-color-anti;
|
||||||
|
}
|
||||||
|
.#{$popup-prefix}-arrow::before {
|
||||||
|
background-color: $status-anti-bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-info {
|
||||||
|
.#{$tooltip-prefix}-wrapper {
|
||||||
|
background-color: $status-info-bg-color;
|
||||||
|
color: $text-color-base;
|
||||||
|
}
|
||||||
|
.#{$popup-prefix}-arrow::before {
|
||||||
|
background-color: $status-info-bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-success {
|
||||||
|
.#{$tooltip-prefix}-wrapper {
|
||||||
|
background-color: $status-success-bg-color;
|
||||||
|
color: $text-color-base;
|
||||||
|
}
|
||||||
|
.#{$popup-prefix}-arrow::before {
|
||||||
|
background-color: $status-success-bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-danger {
|
||||||
|
.#{$tooltip-prefix}-wrapper {
|
||||||
|
background-color: $status-danger-bg-color;
|
||||||
|
color: $text-color-base;
|
||||||
|
}
|
||||||
|
.#{$popup-prefix}-arrow::before {
|
||||||
|
background-color: $status-danger-bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-warning {
|
||||||
|
.#{$tooltip-prefix}-wrapper {
|
||||||
|
background-color: $status-warning-bg-color;
|
||||||
|
color: $text-color-base;
|
||||||
|
}
|
||||||
|
.#{$popup-prefix}-arrow::before {
|
||||||
|
background-color: $status-warning-bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-anti.#{$tooltip-prefix},
|
||||||
|
&-info.#{$tooltip-prefix},
|
||||||
|
&-success.#{$tooltip-prefix},
|
||||||
|
&-danger.#{$tooltip-prefix},
|
||||||
|
&-warning.#{$tooltip-prefix} {
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
.#{$popup-prefix}-arrow::before {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import type { PropType, VNode } from 'vue'
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
import { getPrefixCls } from '../_utils/getPrefixCls'
|
||||||
|
import Popup from '../popup/index'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Tooltip',
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String as PropType<'default' | 'anti' | 'info' | 'success' | 'danger' | 'warning'>,
|
||||||
|
default: 'default',
|
||||||
|
},
|
||||||
|
placement: {
|
||||||
|
type: String as PropType<
|
||||||
|
'top' | 'bottom' | 'left' | 'right'
|
||||||
|
| 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end'
|
||||||
|
| 'left-start' | 'left-end' | 'right-start' | 'right-end'
|
||||||
|
>,
|
||||||
|
default: 'top',
|
||||||
|
},
|
||||||
|
trigger: {
|
||||||
|
type: [String, Array] as PropType<
|
||||||
|
'hover' | 'click' | 'focus' | 'contextMenu' | Array<'hover' | 'click' | 'focus' | 'contextMenu'>
|
||||||
|
>,
|
||||||
|
default: 'hover',
|
||||||
|
},
|
||||||
|
showArrow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
autoFitPopupMinWidth: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
autoFitPopupWidth: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
destroyOnClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
showDelay: { type: Number, default: 0 },
|
||||||
|
hideDelay: { type: Number, default: 0 },
|
||||||
|
class: {
|
||||||
|
type: [String, Array, Object],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
maxWidth: {
|
||||||
|
type: [Number, String] as PropType<number | string>,
|
||||||
|
default: '200px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: [],
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const prefixCls = getPrefixCls('tooltip')
|
||||||
|
|
||||||
|
const renderContent = (content: string | VNode | (() => VNode)) => {
|
||||||
|
if (typeof content === 'function')
|
||||||
|
return content()
|
||||||
|
if (typeof content === 'string') {
|
||||||
|
return <div class={`${prefixCls}-content`}>{content}</div>
|
||||||
|
}
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderTooltip = () => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={[`${prefixCls}-wrapper`, props.class]}
|
||||||
|
style={{
|
||||||
|
maxWidth: props.maxWidth,
|
||||||
|
...props.style,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{slots.content ? slots.content() : renderContent(props.content)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<Popup
|
||||||
|
trigger={props.trigger}
|
||||||
|
placement={props.placement}
|
||||||
|
showArrow={props.showArrow}
|
||||||
|
autoFitPopupMinWidth={props.autoFitPopupMinWidth}
|
||||||
|
autoFitPopupWidth={props.autoFitPopupWidth}
|
||||||
|
destroyOnClose={props.destroyOnClose}
|
||||||
|
content={renderTooltip}
|
||||||
|
showDelay={props.showDelay}
|
||||||
|
hideDelay={props.hideDelay}
|
||||||
|
class={`${prefixCls} ${prefixCls}-${props.type}`}
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
default: () => slots.default?.(),
|
||||||
|
}}
|
||||||
|
</Popup>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -1,40 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useNotification } from '@ao/ao-design'
|
|
||||||
import { h } from 'vue'
|
|
||||||
|
|
||||||
const notification = useNotification()
|
|
||||||
|
|
||||||
function showCustomMessage() {
|
|
||||||
notification.success({
|
|
||||||
title: '测试',
|
|
||||||
subTitle: '测试2222222222222222222222222222222222222222222222222',
|
|
||||||
message: () =>
|
|
||||||
h('div', { style: { color: 'red', position: 'relative' } }, [
|
|
||||||
h(
|
|
||||||
'div',
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
position: 'absolute',
|
|
||||||
bottom: '4px',
|
|
||||||
right: '4px',
|
|
||||||
display: 'flex',
|
|
||||||
gap: '4px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
type: 'success',
|
|
||||||
showClose: true,
|
|
||||||
duration: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="demo">
|
<div class="demo">
|
||||||
<AButton status="primary" @click="showCustomMessage">
|
<div class="row">
|
||||||
自定义 h 函数消息
|
<ATagGroup>
|
||||||
</AButton>
|
<ATag show-close>测试1</ATag>
|
||||||
|
<ATag show-close>测试2</ATag>
|
||||||
|
</ATagGroup>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -46,4 +21,9 @@ function showCustomMessage() {
|
|||||||
gap: 16px;
|
gap: 16px;
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -19,6 +19,9 @@ declare module 'vue' {
|
|||||||
APopconfirm: typeof import('@ao/ao-design')['Popconfirm']
|
APopconfirm: typeof import('@ao/ao-design')['Popconfirm']
|
||||||
APopup: typeof import('@ao/ao-design')['Popup']
|
APopup: typeof import('@ao/ao-design')['Popup']
|
||||||
ASpin: typeof import('@ao/ao-design')['Spin']
|
ASpin: typeof import('@ao/ao-design')['Spin']
|
||||||
|
ATag: typeof import('@ao/ao-design')['Tag']
|
||||||
|
ATagGroup: typeof import('@ao/ao-design')['TagGroup']
|
||||||
ATextarea: typeof import('@ao/ao-design')['Textarea']
|
ATextarea: typeof import('@ao/ao-design')['Textarea']
|
||||||
|
ATooltip: typeof import('@ao/ao-design')['Tooltip']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,19 +187,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 触发元素示例 -->
|
<div style="text-align: center;"><table border="1"><tbody><tr><td colspan="4">Shipper: CHANNEL INTERNATIONAL FREIGHT CO.,LTD 24 FLOOR, YINYI GLOBAL CENTER,B BLOCK,NO.42 YAOHANG STREET HAISHUDISTRICT,NINGBO,CHINA TEL:0086-574-87337359 FAX:0086-574-87135310</td><td rowspan="3" colspan="4">TO:宁波坤洲国际物流有限公司 ATTN: TEL: FROM:宁波驰诺/裘珊珊 TEL:0574-87237893 QQ:1597608137 业务编号:CNNBYS230201 开航日期:2023-02-0400:00:00.0 船公司:现代商船 柜量:2X2OTKFCL运费条款:FREIGHTPREPAID 运输条款:CY-CY</td></tr><tr><td colspan="4">Consignee: NSINTERNATIONAL(THAILAND)CO.LTD 75/49 RICHMOND BLDG.,15 FL SUKHUMVIT SOI 26 KLONGTOEY,BANGKOK1011O THAILAND ATTN:IMPORT@NSINTER.COM TEL: +66-2-665-6710 FAX:+66-2-665-6494</td></tr><tr><td colspan="4">Notify Party: NS INTERNATIONAL (THAILAND) CO.,LTD 75/49 RICHMOND BLDG., 15 FL SUKHUMVIT SOI 26 KLONGTOEY,BANGKOK1011O THAILAND ATTN:IMPORT@NSINTER.COM TEL:+66-2-665-6710 FAX: +66-2-665-6494</td></tr><tr><td colspan="2">起运港(PortOf Loading):</td><td colspan="3">中转港(Port of Dischargc):</td><td colspan="3">目的港(Final Destination):</td></tr><tr><td colspan="2">NINGBO,CHINA</td><td colspan="3"></td><td colspan="3">LEAM CHA BANG</td></tr><tr><td>标志和号码</td><td colspan="2">件数和包装种类</td><td colspan="3">货名</td><td>毛重(公斤)</td><td>体积(立方米)</td></tr><tr><td>SMAU9992165 SMAU9992170</td><td colspan="2">2TANKS</td><td colspan="3">BULK LIQUID ARGON CLASS:2.2 UN:1951</td><td>44000.000KGS</td><td>50.000CBM</td></tr></tbody></table></div>
|
||||||
<button class="trigger" data-tooltip="顶部提示" data-direction="top">顶部</button>
|
|
||||||
<button class="trigger" data-tooltip="顶部左侧提示" data-direction="top-left">顶部左</button>
|
|
||||||
<button class="trigger" data-tooltip="顶部右侧提示" data-direction="top-right">顶部右</button>
|
|
||||||
<button class="trigger" data-tooltip="底部提示" data-direction="bottom">底部</button>
|
|
||||||
<button class="trigger" data-tooltip="底部左侧提示" data-direction="bottom-left">底部左</button>
|
|
||||||
<button class="trigger" data-tooltip="底部右侧提示" data-direction="bottom-right">底部右</button>
|
|
||||||
<button class="trigger" data-tooltip="左侧提示" data-direction="left">左侧</button>
|
|
||||||
<button class="trigger" data-tooltip="左侧顶部提示" data-direction="left-top">左侧顶</button>
|
|
||||||
<button class="trigger" data-tooltip="左侧底部提示" data-direction="left-bottom">左侧底</button>
|
|
||||||
<button class="trigger" data-tooltip="右侧提示" data-direction="right">右侧</button>
|
|
||||||
<button class="trigger" data-tooltip="右侧顶部提示" data-direction="right-top">右侧顶</button>
|
|
||||||
<button class="trigger" data-tooltip="右侧底部提示" data-direction="right-bottom">右侧底</button>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
class TooltipManager {
|
class TooltipManager {
|
||||||
|
|||||||
Reference in new issue
Block a user