diff --git a/examples/sites/demos/pc/app/drawer/default-slot-composition-api.vue b/examples/sites/demos/pc/app/drawer/default-slot-composition-api.vue deleted file mode 100644 index 322a11dec..000000000 --- a/examples/sites/demos/pc/app/drawer/default-slot-composition-api.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - - - diff --git a/examples/sites/demos/pc/app/drawer/default-slot.spec.ts b/examples/sites/demos/pc/app/drawer/default-slot.spec.ts deleted file mode 100644 index 0fc5fc03d..000000000 --- a/examples/sites/demos/pc/app/drawer/default-slot.spec.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { test, expect } from '@playwright/test' - -test('默认插槽', async ({ page }) => { - page.on('pageerror', (exception) => expect(exception).toBeNull()) - await page.goto('drawer#default-slot') - - const drawer = page.locator('.tiny-drawer__main') - await page.getByRole('button', { name: '抽屉默认插槽示例' }).click() - await expect(drawer.locator('.tiny-drawer__body > div')).toHaveClass('my-content') - await expect(drawer.locator('.tiny-drawer__body')).toHaveText('默认插槽内容') -}) diff --git a/examples/sites/demos/pc/app/drawer/default-slot.vue b/examples/sites/demos/pc/app/drawer/default-slot.vue deleted file mode 100644 index 67602ccb1..000000000 --- a/examples/sites/demos/pc/app/drawer/default-slot.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - - - diff --git a/examples/sites/demos/pc/app/drawer/tips-props-composition-api.vue b/examples/sites/demos/pc/app/drawer/tips-props-composition-api.vue new file mode 100644 index 000000000..db8aa45e1 --- /dev/null +++ b/examples/sites/demos/pc/app/drawer/tips-props-composition-api.vue @@ -0,0 +1,23 @@ + + + diff --git a/examples/sites/demos/pc/app/drawer/tips-props.spec.ts b/examples/sites/demos/pc/app/drawer/tips-props.spec.ts new file mode 100644 index 000000000..2bb4205e4 --- /dev/null +++ b/examples/sites/demos/pc/app/drawer/tips-props.spec.ts @@ -0,0 +1,15 @@ +import { test, expect } from '@playwright/test' + +test('帮助提示', async ({ page }) => { + page.on('pageerror', (exception) => expect(exception).toBeNull()) + await page.goto('drawer#tips-props') + + const drawer = page.locator('.tiny-drawer__main') + const helpIcon = drawer.locator('.tiny-drawer__help-icon') + const tooltip = page.getByRole('tooltip', { name: '这是一段帮助提示。。。' }) + + await page.getByRole('button', { name: '展开抽屉' }).click() + await expect(helpIcon).toBeVisible() + await helpIcon.hover() + await expect(tooltip).toBeVisible() +}) diff --git a/examples/sites/demos/pc/app/drawer/tips-props.vue b/examples/sites/demos/pc/app/drawer/tips-props.vue new file mode 100644 index 000000000..a4789bd4d --- /dev/null +++ b/examples/sites/demos/pc/app/drawer/tips-props.vue @@ -0,0 +1,33 @@ + + + diff --git a/examples/sites/demos/pc/app/drawer/webdoc/drawer.js b/examples/sites/demos/pc/app/drawer/webdoc/drawer.js index 7b5ec8b7e..6676ecc34 100644 --- a/examples/sites/demos/pc/app/drawer/webdoc/drawer.js +++ b/examples/sites/demos/pc/app/drawer/webdoc/drawer.js @@ -27,6 +27,16 @@ export default { }, codeFiles: ['placement.vue'] }, + { + demoId: 'tips-props', + name: { 'zh-CN': '帮助提示', 'en-US': 'Help tips' }, + desc: { + 'zh-CN': + '

通过 tips-props 属性可自定义标题帮助提示信息,具体属性配置参考 ToolTip 组件 的 props 说明。

', + 'en-US': '' + }, + codeFiles: ['tips-props.vue'] + }, { demoId: 'width', name: { @@ -139,18 +149,6 @@ export default { }, codeFiles: ['z-index.vue'] }, - { - demoId: 'default-slot', - name: { - 'zh-CN': '默认插槽', - 'en-US': '' - }, - desc: { - 'zh-CN': '

自定义抽屉主体内容。

', - 'en-US': '' - }, - codeFiles: ['default-slot.vue'] - }, { demoId: 'header-slot', name: { diff --git a/packages/design/smb/index.ts b/packages/design/smb/index.ts index 020705ab9..09016f524 100644 --- a/packages/design/smb/index.ts +++ b/packages/design/smb/index.ts @@ -1,6 +1,7 @@ import Alert from './src/alert' import ActionMenu from './src/action-menu' import Popconfirm from './src/popconfirm' +import Drawer from './src/drawer' import Dropdown from './src/dropdown' import DropdownItem from './src/dropdown-item' import Form from './src/form' @@ -17,6 +18,7 @@ export default { Alert, ActionMenu, Popconfirm, + Drawer, Dropdown, DropdownItem, Form, diff --git a/packages/design/smb/src/drawer/index.ts b/packages/design/smb/src/drawer/index.ts new file mode 100644 index 000000000..c7ea991a8 --- /dev/null +++ b/packages/design/smb/src/drawer/index.ts @@ -0,0 +1,5 @@ +export default { + state: { + btnOrderReversed: true + } +} diff --git a/packages/renderless/src/drawer/index.ts b/packages/renderless/src/drawer/index.ts index 08f7d6543..a9f1bbd5b 100644 --- a/packages/renderless/src/drawer/index.ts +++ b/packages/renderless/src/drawer/index.ts @@ -14,7 +14,7 @@ export const computedWidth = return state.width + 'px' } - return props.width || designConfig?.constants.DEFAULT_WIDTH || constants.DEFAULT_WIDTH + return props.width || designConfig?.constants?.DEFAULT_WIDTH || constants.DEFAULT_WIDTH } export const close = diff --git a/packages/renderless/src/drawer/vue.ts b/packages/renderless/src/drawer/vue.ts index 3f8fa3edb..26659badf 100644 --- a/packages/renderless/src/drawer/vue.ts +++ b/packages/renderless/src/drawer/vue.ts @@ -38,7 +38,7 @@ export const renderless = ( width: 0, dragEvent: { x: 0, isDrag: false, offsetWidth: 0 }, computedWidth: computed(() => api.computedWidth()), - isSaasTheme: vm.theme === 'saas' + btnOrderReversed: vm.theme === 'saas' || designConfig?.state?.btnOrderReversed }) Object.assign(api, { diff --git a/packages/theme/src/drawer/aurora-theme.js b/packages/theme/src/drawer/aurora-theme.js index 1a07a25cb..b890e78ba 100644 --- a/packages/theme/src/drawer/aurora-theme.js +++ b/packages/theme/src/drawer/aurora-theme.js @@ -1,7 +1,7 @@ export const tinyDrawerAuroraTheme = { 'ti-drawer-min-width': '30%', 'ti-drawer-close-icon-size': 'var(--ti-common-font-size-3)', - 'ti-drawer-footer-text-align': 'center', + 'ti-drawer-footer-justify-content': 'center', 'ti-drawer-padding-left': '0px', 'ti-drawer-padding-right': '0px', 'ti-drawer-head-title-font-weight': 'var(--ti-common-font-weight-4)', diff --git a/packages/theme/src/drawer/index.less b/packages/theme/src/drawer/index.less index 43f556fe9..01a8018bf 100644 --- a/packages/theme/src/drawer/index.less +++ b/packages/theme/src/drawer/index.less @@ -136,6 +136,7 @@ .@{drawer-prefix-cls}__close { font-size: var(--ti-drawer-close-icon-size); + fill: var(--ti-drawer-close-icon-color); } } @@ -151,7 +152,6 @@ .@{drawer-prefix-cls}__title { max-width: 80%; text-align: left; - padding-right: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -160,6 +160,20 @@ font-weight: var(--ti-drawer-head-title-font-weight); } + .@{drawer-prefix-cls}__header-left { + flex: 1; + display: flex; + align-items: center; + padding-right: 16px; + + .@{drawer-prefix-cls}__help-icon { + width: var(--ti-drawer-help-icon-width-height); + height: var(--ti-drawer-help-icon-width-height); + margin-left: var(--ti-drawer-help-icon-margin-left); + fill: var(--ti-drawer-help-icon-color); + } + } + .@{drawer-prefix-cls}__header-right { justify-content: flex-end; align-items: center; @@ -172,16 +186,39 @@ .@{drawer-prefix-cls}__body { flex: auto; overflow: auto; + padding-left: var(--ti-drawer-padding-left); + padding-right: var(--ti-drawer-padding-right); + border-bottom: 1px solid var(--ti-drawer-divider-body-border-color); } .@{drawer-prefix-cls}__footer { flex: none; display: flex; + align-items: center; justify-content: var(--ti-drawer-footer-justify-content); padding: var(--ti-drawer-footer-padding-top) var(--ti-drawer-footer-padding-right) var(--ti-drawer-footer-padding-bottom) var(--ti-drawer-footer-padding-left); - border-top: 1px solid var(--ti-drawer-divider-border-color); - + border-top: 1px solid var(--ti-drawer-divider-footer-border-color); + + + .@{drawer-prefix-cls}__confirm-btn { + order: 0; + + &.reverse { + margin-left: var(--ti-drawer-divider-footer-button-margin-left); + order: 1; + } + } + + .@{drawer-prefix-cls}__cancel-btn { + margin-left: var(--ti-drawer-divider-footer-button-margin-left); + order: 1; + + &.reverse { + margin-left: 0; + order: 0; + } + } } } } diff --git a/packages/theme/src/drawer/smb-theme.js b/packages/theme/src/drawer/smb-theme.js index 6c59c06f1..7cbc14be2 100644 --- a/packages/theme/src/drawer/smb-theme.js +++ b/packages/theme/src/drawer/smb-theme.js @@ -1,6 +1,13 @@ export const tinyDrawerSmbTheme = { + 'ti-drawer-mask-bg-color': 'rgba(0, 0, 0, 16%)', + 'ti-drawer-shadow': '0 8px 24px rgba(0, 0, 0, 30%)', + 'ti-drawer-head-title-font-size': 'var(--ti-common-font-size-4)', 'ti-drawer-padding-right': 'var(--ti-common-space-8x)', 'ti-drawer-footer-padding-top': 'var(--ti-common-space-6x)', 'ti-drawer-divider-border-color': 'transparent', - 'ti-drawer-close-icon-size': 'var(--ti-common-font-size-2)' + 'ti-drawer-divider-body-border-color': 'var(--ti-common-color-line-dividing)', + 'ti-drawer-divider-footer-border-color': 'var(--ti-common-color-transparent)', + 'ti-drawer-close-icon-size': 'var(--ti-common-font-size-5)', + 'ti-drawer-help-icon-color': 'var(--ti-common-color-icon)', + 'ti-drawer-close-icon-color': 'var(--ti-common-color-icon-normal)' } diff --git a/packages/theme/src/drawer/vars.less b/packages/theme/src/drawer/vars.less index c805bff6c..e27019869 100644 --- a/packages/theme/src/drawer/vars.less +++ b/packages/theme/src/drawer/vars.less @@ -21,6 +21,8 @@ --ti-drawer-padding-left: var(--ti-common-space-8x, 32px); // 右内边距 --ti-drawer-padding-right: var(--ti-common-space-10x, 40px); + // 遮罩层背景色 + --ti-drawer-mask-bg-color: rgba(0, 0, 0, 0.3); // 阴影 --ti-drawer-shadow: var(--ti-common-shadow-4-down, 0 8px 40px 0 rgba(0, 0, 0, 0.2)); // 头部与底部边框颜色 @@ -42,8 +44,10 @@ --ti-drawer-head-title-font-size: var(--ti-common-font-size-2, 16px); // 头部文本色(hide) --ti-drawer-head-text-color: var(--ti-common-color-text-primary, #252b3a); - // 头部字重 + // 头部标题字重 --ti-drawer-head-title-font-weight: var(--ti-common-font-weight-7, bold); + // 头部标题字体色 + --ti-drawer-head-title-text-color: var(--ti-common-text-primary, #252b3a); // 关闭按钮宽度 --ti-drawer-btn-width: var(--ti-common-size-8x, 32px); // 关闭按钮高度 @@ -52,12 +56,20 @@ --ti-drawer-close-icon-size: var(--ti-common-font-size-1, 14px); // 关闭按钮圆角 --ti-drawer-btn-border-radius: var(--ti-common-border-radius-1, 4px); + // 关闭按钮图标色 + --ti-drawer-close-icon-color: var(--ti-common-color-icon-normal, #575d6c); // 关闭按钮悬浮图标色 --ti-drawer-close-icon-color-hover: var(--ti-common-color-icon-hover, #5e7ce0); // 关闭按钮与上边框的距离(hide) --ti-drawer-btn-position-top: var(--ti-common-space-5x, 20px); // 关闭按钮与右边框的距离(hide) --ti-drawer-btn-position-right: var(--ti-common-space-5x, 20px); + // 标题与帮助图标间距 + --ti-drawer-help-icon-margin-left: var(--ti-common-space-2x, 8px); + // 帮助图标宽高 + --ti-drawer-help-icon-width-height: var(--ti-common-space-4x, 16px); + // 帮助图标色 + --ti-drawer-help-icon-color: var(--ti-common-color-info, #252b3a); // 内容上内边距 --ti-drawer-body-padding-top: var(--ti-common-space-0, 0); @@ -67,6 +79,8 @@ --ti-drawer-body-padding-left: var(--ti-common-space-0, 0); // 内容右内边距 --ti-drawer-header-padding-right: var(--ti-common-space-0, 0); + // 内容底部边框色(hide) + --ti-drawer-divider-body-border-color: var(--ti-common-color-transparent); // 底部按钮对齐方式 --ti-drawer-footer-justify-content: flex-end; // 底部上内边距 @@ -81,4 +95,8 @@ --ti-drawer-footer-margin-left: var(--ti-common-space-8x, 32px); // 底部右外边距 --ti-drawer-footer-margin-right: var(--ti-common-space-10x, 40px); + // 底部按钮间距 + --ti-drawer-divider-footer-button-margin-left: var(--ti-common-space-2x, 8px); + // 底部边框色(hide) + --ti-drawer-divider-footer-border-color: var(--ti-drawer-divider-border-color, #dfe1e6); } diff --git a/packages/vue/src/drawer/package.json b/packages/vue/src/drawer/package.json index 8e81bfde8..0aec54e3c 100644 --- a/packages/vue/src/drawer/package.json +++ b/packages/vue/src/drawer/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@opentiny/vue-button": "workspace:~", + "@opentiny/vue-tooltip": "workspace:~", "@opentiny/vue-common": "workspace:~", "@opentiny/vue-renderless": "workspace:~" }, diff --git a/packages/vue/src/drawer/src/index.ts b/packages/vue/src/drawer/src/index.ts index f1bd51106..c9fcbbecc 100644 --- a/packages/vue/src/drawer/src/index.ts +++ b/packages/vue/src/drawer/src/index.ts @@ -62,7 +62,8 @@ export const drawerProps = { type: Number, default: 2000 }, - beforeClose: Function + beforeClose: Function, + tipsProps: Object } export default { diff --git a/packages/vue/src/drawer/src/pc.vue b/packages/vue/src/drawer/src/pc.vue index 3aad3c534..0dcd503e0 100644 --- a/packages/vue/src/drawer/src/pc.vue +++ b/packages/vue/src/drawer/src/pc.vue @@ -42,7 +42,12 @@
-
{{ title }}
+
+
{{ title }}
+ + + +
@@ -73,13 +78,16 @@ {{ t('ui.button.confirm') }} - {{ - t('ui.button.cancel') - }} + {{ t('ui.button.cancel') }}
@@ -92,13 +100,16 @@ import { renderless, api } from '@opentiny/vue-renderless/drawer/vue' import { setup, props } from '@opentiny/vue-common' import '@opentiny/vue-theme/drawer/index.less' -import { IconClose } from '@opentiny/vue-icon' +import { iconClose, iconHelpCircle } from '@opentiny/vue-icon' import Button from '@opentiny/vue-button' +import Tooltip from '@opentiny/vue-tooltip' export default { components: { TinyButton: Button, - IconClose: IconClose() + TinyTooltip: Tooltip, + IconClose: iconClose(), + IconHelpCircle: iconHelpCircle() }, props: [ ...props, @@ -116,7 +127,8 @@ export default { 'flex', 'showClose', 'zIndex', - 'beforeClose' + 'beforeClose', + 'tipsProps' ], setup(props, context) { return setup({ props, context, renderless, api })